from apps.productos.models import Producto, Categoria, Venta, VentaProducto
from django import forms

class ProductoForm(forms.ModelForm):
    class Meta:
        model = Producto

        fields = [
            'id_cliente',
            'nombre',
            'precio',
            'foto',
            'existencias',
            'categoria',
        ]

        labels = {
            'id_cliente': 'Id Cliente',
            'nombre': 'Nombre',
            'precio': 'Precio',
            'foto': 'Foto',
            'existencias': 'Existencias',
            'categoria': 'Categoria',

        }

    def __init__(self, *args, **kwargs):
        super(ProductoForm, self).__init__(*args, **kwargs)
        self.fields['id_cliente'].widget = forms.HiddenInput()
        self.fields['nombre'].widget.attrs.update({'placeholder': 'Digite el Nombre Del Producto'})
        self.fields['precio'].widget.attrs.update({'placeholder': 'Digite el Precio Del Producto'})
        self.fields['existencias'].widget.attrs.update({'placeholder': 'Digite las Existencias Del Producto'})
        self.fields['categoria'].widget.attrs.update({'placeholder': 'Digite la Categoria Del Producto'})

        for field in self.fields:
            self.fields[field].widget.attrs.update({'class': 'form-control'})

class CategoriaForm(forms.ModelForm):
    class Meta:
        model = Categoria

        fields = [
            'nombre',
        ]

        labels = {
            'nombre':'Nombre',
        }

        widgets = {
            'nombre': forms.TextInput(attrs={'class':'form-control'}),
        }

class VentaForm(forms.ModelForm):
    class Meta:
        model = Venta

        fields = [
            'fecha',
            'total',
            'id_producto',
            'id_tienda',
            'firstname_cliente',
            'lastname_cliente',
            'pais_cliente',
            'direccion_cliente',
            'ciudad_cliente',
            'telefono_cliente',
            'correo_cliente',
        ]

        labels = {
            'fecha': 'Fecha',
            'total': 'Total',
            'id_producto': 'Id Producto',
            'id_tienda': 'Id Tienda',
            'firstname_cliente':'Nombres',
            'lastname_cliente':'Apellidos',
            'pais_cliente':'Pais',
            'direccion_cliente':'Direccion',
            'ciudad_cliente':'Ciudad',
            'telefono_cliente':'Telefono',
            'correo_cliente':'Correo',
        }

    def __init__(self, *args, **kwargs):
        super(VentaForm, self).__init__(*args, **kwargs)
        self.fields['fecha'].widget = forms.HiddenInput()
        self.fields['total'].widget = forms.HiddenInput()
        self.fields['id_producto'].widget = forms.HiddenInput()
        self.fields['id_tienda'].widget = forms.HiddenInput()
        self.fields['firstname_cliente'].widget.attrs.update({'placeholder': 'Digite sus Nombres'})
        self.fields['lastname_cliente'].widget.attrs.update({'placeholder': 'Digite su Apellidos'})
        self.fields['pais_cliente'].widget.attrs.update({'placeholder': 'Digite su Pais'})
        self.fields['direccion_cliente'].widget.attrs.update({'placeholder': 'Digite su Direccion'})
        self.fields['ciudad_cliente'].widget.attrs.update({'placeholder': 'Digite su Ciudad'})
        self.fields['telefono_cliente'].widget.attrs.update({'placeholder': 'Digite su Telefono'})
        self.fields['correo_cliente'].widget.attrs.update({'placeholder': 'Digite su Correo'})

        for field in self.fields:
            self.fields[field].widget.attrs.update({'class': 'form-control'})

class VentaProductoForm(forms.ModelForm):
    class Meta:
        model = VentaProducto

        fields = [
            'cantidad',
            'precio_venta',
            'descuento',
            'producto',
            'venta',
        ]

        labels = {
            'cantidad': 'Cantidad',
            'precio_venta': 'Precio',
            'descuento': 'Descuento',
            'producto': 'Producto',
            'venta': 'Venta',
        }

    def __init__(self, *args, **kwargs):
        super(VentaProductoForm, self).__init__(*args, **kwargs)

        for field in self.fields:
            self.fields[field].widget.attrs.update({'class': 'form-control'})


import turtle

## 전역 변수 선언 부분 ##
num1, num2, res = 0, 0, 0  # 입력 받을 10진수
swidth, sheight = 1000, 300  # 윈도창의 폭과 넓이
curX, curY = 0, 0  # 거북이의 현재 위치

## 거북이로 2진수 숫자 표현하기 ##

def binToTurtle(binary, num):
    curX = swidth / 2  # 거북이 초기 위치를 윈도창 오른쪽 끝으로 설정
    for i in range(len(binary) - 2):  # 5를 입력시 0b101이므로 앞 0b를 제외한 101 글자 수에 해당하는 3번을 반족
        turtle.goto(curX, curY)  # 거북이랑 계산된 좌표로 이동
        if num & 1:  # 2진수로 변환했을 때 맨 하위 비트가 1인지 체크
            turtle.color('red')
            turtle.turtlesize(2)
        else:
            turtle.color('blue')
            turtle.turtlesize(1)
        turtle.stamp()  # 위에서 설정된 크기와 색상으로 거북이 도장을 현재 위치에 찍는다.
        curX -= 50  # X좌표를 왼쪽으로 50만큼 이동시킨다.
        num >>= 1  # 숫자를 오른쪽을 1 시프트시킨다. 오른쪽 비트는 이미 앞에서 표현했으므로 제거

## 메인 코드 부분 ##
if __name__ == "__main__":
    turtle.title('2진수와 비트 논리곱의 결과 2진수를 출력하는 프로그램')
    turtle.shape('turtle')
    turtle.setup(width=swidth + 50, height=sheight + 50)
    turtle.screensize(swidth, sheight)
    turtle.penup()
    turtle.left(90)  # 거북이가 위쪽을 바라보도록 설정

    num1, num2 = map(int, input('두 개의 숫자를 입력하세요: ').split(' '))
    curY = 0
    binToTurtle(bin(num1), num1)  # 입력받은 숫자를 2진수 문자열로 변환

    curY = -50
    binToTurtle(bin(num2), num2)

    curY = -100
    res = num1 & num2
    binToTurtle(bin(res), res)

turtle.done()


import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.nn import functional as F

class myRNN(nn.Module):
    def __init__(self, config):
        super(myRNN, self).__init__()

        self.hidden_size = 30  # Dimension of hidden state
        self.embedding_length = config.wordvec_dim
        self.num_layers = 2  # Stack layers
        self.embedding_length = config.wordvec_dim
        self.word_embeddings = nn.Embedding(
            config.weight.shape[0], self.embedding_length)  # Embedding layer
        self.word_embeddings = self.word_embeddings.from_pretrained(
            config.weight, freeze=False)  # Load pretrianed word embedding, and fine-tuing
        self.recurrent = nn.RNN(self.embedding_length, self.hidden_size,
                                num_layers=self.num_layers, bidirectional=True, batch_first=True)  # Recurrent layer
        self.fc = nn.Linear(2*self.num_layers *
                            self.hidden_size, config.label_num)  # FC layer

    def forward(self, input_sentences):

        x = self.word_embeddings(input_sentences)  # (batch_size, batch_dim, embedding_length)
        # print(x.size())

        output, h_n = self.recurrent(x)  # 特征，隐状态
        # print(h_n.size())
        # h_n.size() = (2*self.num_layers, batch_size, hidden_size), 2 for bidirectional

        # (batch_size, 2*self.num_layers, hidden_size)
        h_n = h_n.permute(1, 0, 2)

        h_n = h_n.contiguous().view(h_n.size()[0], h_n.size()[1]*h_n.size()[2])  # (batch_size, 4*hidden_size)
        # print(h_n.size())

        logits = self.fc(h_n)  # (batch_size, label_num)

        return F.softmax(logits, dim=1)

class LSTMClassifier(nn.Module):
    def __init__(self, config):
        super(LSTMClassifier, self).__init__()

        self.label_num = config.label_num
        self.hidden_size = 150
        self.embedding_length = config.wordvec_dim
        self.word_embeddings = nn.Embedding(
            config.weight.shape[0], self.embedding_length)  # Embedding layer
        self.word_embeddings = self.word_embeddings.from_pretrained(
            config.weight, freeze=False)  # Load pretrianed word embedding, and fine-tuing

        self.lstm = nn.LSTM(self.embedding_length,
                            self.hidden_size, batch_first=True)  # lstm
        self.fc = nn.Linear(self.hidden_size, self.label_num)

    def forward(self, input_sentence):
        x = self.word_embeddings(input_sentence)  # (batch_size, batch_dim, embedding_length)

        output, (final_hidden_state, final_cell_state) = self.lstm(x)

        logits = self.fc(final_hidden_state[-1])  # final_hidden_state.size() = (1, batch_size, hidden_size) & logits.size() = (batch_size, label_num)

        return F.softmax(logits, dim=1)


#!/usr/bin/python3

import matplotlib.pyplot as plt
import numpy as np
from typing import List, Tuple, Union
from PIL import Image
import time
import os

RADIUS = 150  # aim to 20 cm (/7.5)
SCREWS_AMOUNT = 210  # better resolution in 470
STRING_LENGTH = 7.5 * RADIUS * 615
THREAD_WEIGHT = 13
DISTANCE_WEIGHT = 20.7

class Gui:
    def __init__(self, screws_position: List[Tuple[float, float]]):
        self._screws_position = screws_position

    def draw_strings(self, strings: List[Tuple[int, int]]) -> None:
        for line in strings:
            self._draw_screws_string_connection(line[0], line[1])

    def draw_screws(self, labels=False) -> None:
        plt.scatter(self._screws_position[:, 0], self._screws_position[:, 1], s=1)
        if not labels:
            return
        for i, sc in enumerate(self._screws_position[::10]):
            plt.text(sc[0], sc[1], str(i * 10))

    def _draw_screws_string_connection(self, screw1: int, screw2: int) -> None:
        pos_1 = self._screws_position[screw1]
        pos_2 = self._screws_position[screw2]
        plt.plot([pos_1[0], pos_2[0]], [pos_1[1], pos_2[1]],
                 alpha=0.99, c='black', linewidth=0.233)

    def show(self) -> None:
        plt.axis('off')
        plt.gcf().tight_layout()
        plt.gca().invert_yaxis()
        plt.gcf().gca().set_aspect('equal', 'datalim')
        plt.show()

class Engine:
    def __init__(self, image_path: str, preprocess: bool = True):
        self._screws_position = None
        self._image = None
        self._distances = None
        self._samples = None
        self._prepare_image(image_path)
        self._init_screws()
        if preprocess:
            self._init_distances_and_samples()

    def _prepare_image(self, image_path: str) -> None:
        # load image as grayscale
        im = np.array(Image.open(image_path).convert('L'))
        # crop image to circle center
        center = np.floor(0.5 * np.array(im.shape)).astype(np.int32)
        im_radius = min(center)
        im_crop = im[center[0] - im_radius: center[0] + im_radius,
                  center[1] - im_radius: center[1] + im_radius]
        # scale to circle size
        im = np.array(Image.fromarray(im_crop).resize((RADIUS * 2 + 1, RADIUS * 2 + 1)))
        im = (100 / 255) * im
        self._image = im.copy()
        # TODO consider quantisizing, blurring, normalizing to gray

    def _init_screws(self) -> None:
        x0, y0 = np.array(self._image.shape[::-1]) * 0.5
        rads = (2 * np.pi / SCREWS_AMOUNT) * np.arange(SCREWS_AMOUNT)
        xys = np.array([[x0 + RADIUS * np.sin(angle), y0 + RADIUS * np.cos(angle)]
                        for angle in rads])
        self._screws_position = xys

    def _init_distances_and_samples(self) -> None:
        preprocessed_path = f'preprocessed_{RADIUS}_{SCREWS_AMOUNT}.npy'
        if os.path.exists(preprocessed_path):
            loaded_preprocessed = np.load(preprocessed_path, allow_pickle=True)
            self._distances, self._samples = loaded_preprocessed
            print('Working with preprocessed data.')
        else:
            assert self._screws_position is not None, 'screws not initialized'
            all_screws_pos = np.array(self._screws_position)
            all_screws_x_diff = np.subtract.outer(all_screws_pos[:, 0], all_screws_pos[:, 0])
            all_screws_y_diff = np.subtract.outer(all_screws_pos[:, 1], all_screws_pos[:, 1])
            self._distances = np.sqrt(np.sum(np.power(np.stack((all_screws_x_diff, all_screws_y_diff)), 2), axis=0))

            # TODO vectorise? (preprocess optimization is less crucial).
            self._samples = {}
            for i1, p1 in enumerate(self._screws_position):
                for i2, p2 in enumerate(self._screws_position[i1 + 1:], i1 + 1):
                    euclidean_distance = self._distances[i1, i2]
                    sample_rate = np.arange(np.floor(euclidean_distance - 1)) / euclidean_distance
                    xs = np.hstack([p1[0] + (p2[0] - p1[0]) * sample_rate, p2[0]])
                    ys = np.hstack([p1[1] + (p2[1] - p1[1]) * sample_rate, p2[1]])
                    self._samples[(i1, i2)] = (xs, ys)
            np.save(preprocessed_path[:-4], (self._distances, self._samples))
            print('saved preprocessed data.')

    def get_distance(self, screw1: int, screw2: int) -> float:
        if not (0 <= screw1 < SCREWS_AMOUNT) or \
                not (0 <= screw2 < SCREWS_AMOUNT):
            raise IndexError
        # s1, s2 = min(screw1, screw2), max(screw1, screw2)  # no need, profit is low.
        return self._distances[screw1, screw2]

    def sample_line(self, screw1: int, screw2: int) -> Tuple[List[float], List[float]]:
        if not (0 <= screw1 < SCREWS_AMOUNT) or \
                not (0 <= screw2 < SCREWS_AMOUNT):
            raise IndexError
        s1, s2 = min(screw1, screw2), max(screw1, screw2)
        return self._samples[(s1, s2)]

    def get_screws_positions(self) -> List[Tuple[float, float]]:  # each screw's (x,y)
        assert self._screws_position is not None, 'screws not initialized'
        return self._screws_position.copy()

    def get_image(self):
        return self._image

    @staticmethod
    def just_try(randomize: bool, connected: bool) -> Union[List[List[int]], List[Tuple[int, int]]]:
        if randomize:
            amount = 500
            if connected:
                return Engine.steps_to_tuples(np.random.randint(SCREWS_AMOUNT, size=amount))
            else:
                return np.random.randint(SCREWS_AMOUNT, size=(amount, 2))
        else:
            jump = 70
            return np.vstack([np.arange(SCREWS_AMOUNT - jump),
                              np.arange(SCREWS_AMOUNT - jump) + jump]).T

    @staticmethod
    def steps_to_tuples(steps: List[int]) -> List[Tuple[int, int]]:
        return list(zip(steps[:-1], steps[1:]))

# TODO separate all classes to different files.

class Algo:
    def __init__(self, engine):
        self._leftover_string = STRING_LENGTH
        self._engine = engine
        self._curr_state = engine.get_image().copy()
        self._steps = None

    def _update_state(self, from_screw: int, to_screw: int, state):
        xs, ys = self._engine.sample_line(from_screw, to_screw)
        ys = np.round(ys).astype(np.int)
        xs = np.round(xs).astype(np.int)
        ys = ys.clip(0, state.shape[0] - 1)
        xs = xs.clip(0, state.shape[1] - 1)
        edited_state = state.copy()
        edited_state[ys, xs] += THREAD_WEIGHT
        return edited_state

    def _get_next_naive(self, current_screw: int, state) -> Tuple[int, float]:
        if not (0 <= current_screw < SCREWS_AMOUNT):
            raise IndexError
        best_candidate = current_screw
        while best_candidate == current_screw:
            best_candidate = (current_screw + np.random.randint(SCREWS_AMOUNT)) % SCREWS_AMOUNT
        best_score = self._score_line_naive(current_screw, best_candidate, state)
        for screw_i in range(SCREWS_AMOUNT):
            if screw_i in (current_screw, best_candidate):
                continue
            score = self._score_line_naive(current_screw, screw_i, state)
            if score > best_score:
                best_candidate = screw_i
                best_score = score
        return best_candidate, best_score

    def _score_path_aux(self, degree: int, current_screw: int, next_screw: int,
                        state) -> Tuple[float, float, np.ndarray, List[int]]:
        state = self._update_state(current_screw, next_screw, state)
        cur2next_score = self._score_line_naive(current_screw, next_screw, state)
        cur2next_amount = self._engine.get_distance(current_screw, next_screw)
        score, amount, c_state, c_screws = self._get_path(degree - 1, next_screw, state)
        return cur2next_score + score, cur2next_amount + amount, c_state, [next_screw] + c_screws

    def _get_path(self, degree: int, current_screw: int, state) -> Tuple[float, float, np.ndarray, List[int]]:
        # recursively get the best next and returns (accumulative score, accumulative amount, state, final screw)
        assert degree > 0, f'Algo::_get_path called with invalid degree: {degree}'
        if degree == 1:
            following_screw, following_score = self._get_next_naive(current_screw, state)
            assert following_screw != current_screw
            following_state = self._update_state(current_screw, following_screw, state)
            following_amount = self._engine.get_distance(current_screw, following_screw)
            return following_score, following_amount, following_state, [following_screw]
        else:
            # typedef:   b_ prefix for best_something;  c_ prefix for candidate_something.
            best_candidate = current_screw
            while best_candidate == current_screw:
                best_candidate = (current_screw + np.random.randint(SCREWS_AMOUNT)) % SCREWS_AMOUNT
            b_score, b_amount, b_state, b_screws = self._score_path_aux(degree, current_screw, best_candidate, state)
            for screw_i in range(SCREWS_AMOUNT):
                if screw_i in (current_screw, best_candidate):
                    continue
                c_score, c_amount, c_state, c_screws = self._score_path_aux(degree, current_screw, screw_i, state)
                if c_score > b_score:
                    best_candidate = screw_i
                    b_score, b_amount, b_state, b_screws = c_score, c_amount, c_state, c_screws
            assert len(b_screws) == degree
            return b_score, b_amount, b_state, b_screws

    def _score_line_naive(self, screw1: int, screw2: int, state) -> float:
        xs, ys = self._engine.sample_line(screw1, screw2)
        ys = np.round(ys).astype(np.int)
        xs = np.round(xs).astype(np.int)
        ys = ys.clip(0, state.shape[0] - 1)
        xs = xs.clip(0, state.shape[1] - 1)
        return (-1 * np.sum(state[ys, xs])) / (DISTANCE_WEIGHT*self._engine.get_distance(screw1, screw2))

    def execute(self, degree: int) -> List[int]:
        current_screw = np.random.randint(SCREWS_AMOUNT)
        next_screws = [current_screw]
        steps = []
        modulus = 7 - (degree ** 2)
        while self._leftover_string > 0:
            score, amount, next_state, next_screws = self._get_path(degree, current_screw=current_screw,
                                                                    state=self._curr_state)
            steps.extend([current_screw] + next_screws[:-1])
            current_screw = next_screws[-1]
            self._leftover_string -= amount
            self._curr_state = next_state
            if len(steps) % modulus == 0:
                print(f'leftover: {self._leftover_string}')
        steps.append(next_screws[-1])
        return steps

def main_load(image_path: str, steps_path: str):
    infrastructure_engine = Engine(image_path, preprocess=False)
    steps = np.load(steps_path)
    steps = steps[1000:]
    steps = np.mod(steps + 157, 210)  # steps = np.roll(steps, 157)
    tup_steps = infrastructure_engine.steps_to_tuples(steps)
    print(len(steps))
    ui = Gui(infrastructure_engine.get_screws_positions())
    ui.draw_screws()
    ui.draw_strings(tup_steps)
    ui.show()
    stxt = 209 - steps
    with open('out_steps.txt', 'w') as f:
        f.write(', '.join([str(x) for x in stxt]))
    print(stxt)

def main(image_path: str, calculate_only: bool = False):
    print(f'Running with string length {STRING_LENGTH / (7.5 * 100 * 1000)} km, to create a circle with radius '
          f'{RADIUS / 6} cm, with {SCREWS_AMOUNT} screws.')
    infrastructure_engine = Engine(image_path)
    ui = Gui(infrastructure_engine.get_screws_positions())

    algo = Algo(infrastructure_engine)
    begin_time = time.time()
    res_steps = algo.execute(1)
    endtime = time.time()
    np.save(f'last_run_{STRING_LENGTH / (7.5 * 100 * 1000)}_{RADIUS / 7.5}_{SCREWS_AMOUNT}', res_steps)
    print('Algo time: ', endtime - begin_time)
    print('Steps amount: ', len(res_steps))

    # trial = infrastructure_engine.just_try(randomize=True, connected=True)
    if not calculate_only:
        ui.draw_screws()
        # plt.imshow(infrastructure_engine.get_image())
        ui.draw_strings(infrastructure_engine.steps_to_tuples(res_steps))
        ui.show()

if __name__ == '__main__':
    my_photo = '/home/ru/Pictures/myphotox2.jpg'
    main(my_photo)
    # npy_steps_path = '/home/ru/develop/StringsImage/list146.npy'
    # final_npy_steps_path = '/home/ru/develop/StringsImage/mypicture34.pnglast_run_3.0_25.0_210.npy'
    # main_load(my_photo, final_npy_steps_path)


import random
list = []
upperLimit = 100
for i in range(1, upperLimit):
    list.insert (i, random.randrange(9999))
print ("Total items inserted into the list:" , len(list))
leastVal = list[0]
for i in range(1, upperLimit - 1):
    if list[i] < leastVal:
        leastVal = list[i]

print("Least value in the list: ", leastVal)


# adapted from https://github.com/molecularsets/moses/blob/7b8f83b21a9b7ded493349ec8ef292384ce2bb52/moses/metrics/metrics.py

import torch
import warnings
from multiprocessing import Pool
import numpy as np
from scipy.spatial.distance import cosine as cos_distance
from scipy.stats import wasserstein_distance

# scikit-learn bootstrap

from moses.dataset import get_dataset, get_statistics
from moses.utils import mapper
from moses.utils import disable_rdkit_log, enable_rdkit_log
from moses.metrics.utils import compute_fragments, average_agg_tanimoto, \
    compute_scaffolds, fingerprints, \
    get_mol, canonic_smiles, mol_passes_filters

import pandas as pd

def get_some_metrics(gen,
                     k=None,
                     n_jobs=1,
                     device='cpu',
                     batch_size=512,
                     pool=None,
                     test=None,
                     test_scaffolds=None,
                     ptest=None,
                     ptest_scaffolds=None):
    """
    Computes all available metrics between test (scaffold test)
    and generated sets of SMILES.
    Parameters:
        gen: list of generated SMILES
        k: int or list with values for unique@k. Will calculate number of
            unique molecules in the first k molecules. Default [1000, 10000]
        n_jobs: number of workers for parallel processing
        device: 'cpu' or 'cuda:n', where n is GPU device number
        batch_size: batch size for FCD metric
        pool: optional multiprocessing pool to use for parallelization
        test (None or list): test SMILES. If None, will load
            a default test set
        test_scaffolds (None or list): scaffold test SMILES. If None, will
            load a default scaffold test set
        ptest (None or dict): precalculated statistics of the test set. If
            None, will load default test statistics. If you specified a custom
            test set, default test statistics will be ignored
        ptest_scaffolds (None or dict): precalculated statistics of the
            scaffold test set If None, will load default scaffold test
            statistics. If you specified a custom test set, default test
            statistics will be ignored
        train (None or list): train SMILES. If None, will load a default
            train set
    Available metrics:
        * %valid
        * %unique@k
        * Frechet ChemNet Distance (FCD)
        * Fragment similarity (Frag)
        * Scaffold similarity (Scaf)
        * Similarity to nearest neighbour (SNN)
        * Internal diversity (IntDiv)
        * Internal diversity 2: using square root of mean squared
            Tanimoto similarity (IntDiv2)
        * %passes filters (Filters)
        * Distribution difference for logP, SA, QED, weight
        * Novelty (molecules not present in train)
    """
    if test is None:
        if ptest is not None:
            raise ValueError("You cannot specify custom test "
                             "statistics for default test set")
        test = get_dataset('test')
        ptest = get_statistics('test')

    if test_scaffolds is None:
        if ptest_scaffolds is not None:
            raise ValueError("You cannot specify custom scaffold test "
                             "statistics for default scaffold test set")
        test_scaffolds = get_dataset('test_scaffolds')
        ptest_scaffolds = get_statistics('test_scaffolds')

    if k is None:
        k = [1000, 10000]

    disable_rdkit_log()
    metrics = {}
    close_pool = False
    if pool is None:
        if n_jobs != 1:
            pool = Pool(n_jobs)
            close_pool = True
        else:
            pool = 1
    metrics['valid'] = fraction_valid(gen, n_jobs=pool)
    gen = remove_invalid(gen, canonize=True)
    test = remove_invalid(test, canonize=True)
    if not isinstance(k, (list, tuple)):
        k = [k]
    for _k in k:
        metrics['unique@{}'.format(_k)] = fraction_unique(gen, _k, pool)

    if ptest is None:
        ptest = compute_intermediate_statistics(test,
                                                n_jobs=n_jobs,
                                                device=device,
                                                batch_size=batch_size,
                                                pool=pool)

    mols = mapper(pool)(get_mol, gen)
    kwargs = {'n_jobs': pool, 'device': device, 'batch_size': batch_size}
    metrics['SNN/Test'], metrics['Novelty/Test'] = SNNMetric(**kwargs)(
        gen=mols, pref=ptest['SNN'])
    metrics['Frag/Test'] = FragMetric(**kwargs)(gen=mols, pref=ptest['Frag'])
    metrics['Scaf/Test'] = ScafMetric(**kwargs)(gen=mols, pref=ptest['Scaf'])

    enable_rdkit_log()
    if close_pool:
        pool.close()
        pool.join()
    return metrics

def compute_intermediate_statistics(smiles,
                                    n_jobs=1,
                                    device='cpu',
                                    batch_size=512,
                                    pool=None):
    """
    The function precomputes statistics such as mean and variance for FCD, etc.
    It is useful to compute the statistics for test and scaffold test sets to
        speedup metrics calculation.
    """
    close_pool = False
    if pool is None:
        if n_jobs != 1:
            pool = Pool(n_jobs)
            close_pool = True
        else:
            pool = 1
    statistics = {}
    mols = mapper(pool)(get_mol, smiles)
    kwargs = {'n_jobs': pool, 'device': device, 'batch_size': batch_size}
    statistics['SNN'] = SNNMetric(**kwargs).precalc(mols)
    statistics['Frag'] = FragMetric(**kwargs).precalc(mols)
    statistics['Scaf'] = ScafMetric(**kwargs).precalc(mols)
    if close_pool:
        pool.terminate()
    return statistics

def fraction_passes_filters(gen, n_jobs=1):
    """
    Computes the fraction of molecules that pass filters:
    * MCF
    * PAINS
    * Only allowed atoms ('C','N','S','O','F','Cl','Br','H')
    * No charges
    """
    passes = mapper(n_jobs)(mol_passes_filters, gen)
    return np.mean(passes)

def internal_diversity(gen,
                       n_jobs=1,
                       device='cpu',
                       fp_type='morgan',
                       gen_fps=None,
                       p=1):
    """
    Computes internal diversity as:
    1/|A|^2 sum_{x, y in AxA} (1-tanimoto(x, y))
    """
    if gen_fps is None:
        gen_fps = fingerprints(gen, fp_type=fp_type, n_jobs=n_jobs)
    return 1 - (average_agg_tanimoto(
        gen_fps, gen_fps, agg='mean', device=device, p=p)).mean()

def fraction_unique(gen, k=None, n_jobs=1, check_validity=True):
    """
    Computes a number of unique molecules
    Parameters:
        gen: list of SMILES
        k: compute unique@k
        n_jobs: number of threads for calculation
        check_validity: raises ValueError if invalid molecules are present
    """
    if k is not None:
        if len(gen) < k:
            warnings.warn("Can't compute unique@{}.".format(k) +
                          "gen contains only {} molecules".format(len(gen)))
        gen = gen[:k]
    canonic = set(mapper(n_jobs)(canonic_smiles, gen))
    if None in canonic and check_validity:
        raise ValueError("Invalid molecule passed to unique@k")
    return len(canonic) / len(gen)

def fraction_valid(gen, n_jobs=1):
    """
    Computes a number of valid molecules
    Parameters:
        gen: list of SMILES
        n_jobs: number of threads for calculation
    """
    gen = mapper(n_jobs)(get_mol, gen)
    return 1 - gen.count(None) / len(gen)

def novelty(gen, train, n_jobs=1):
    gen_smiles = mapper(n_jobs)(canonic_smiles, gen)
    gen_smiles_set = set(gen_smiles) - {None}
    train_set = set(train)
    return len(gen_smiles_set - train_set) / len(gen_smiles_set)

def remove_invalid(gen, canonize=True, n_jobs=1):
    """
    Removes invalid molecules from the dataset
    """
    if not canonize:
        mols = mapper(n_jobs)(get_mol, gen)
        return [gen_ for gen_, mol in zip(gen, mols) if mol is not None]
    return [x for x in mapper(n_jobs)(canonic_smiles, gen) if x is not None]

class Metric:

    def __init__(self, n_jobs=1, device='cpu', batch_size=512, **kwargs):
        self.n_jobs = n_jobs
        self.device = device
        self.batch_size = batch_size
        for k, v in kwargs.values():
            setattr(self, k, v)

    def __call__(self, ref=None, gen=None, pref=None, pgen=None):
        assert (ref is None) != (pref is None), "specify ref xor pref"
        assert (gen is None) != (pgen is None), "specify gen xor pgen"
        if pref is None:
            pref = self.precalc(ref)
        if pgen is None:
            pgen = self.precalc(gen)
        return self.metric(pref, pgen)

    def precalc(self, moleclues):
        raise NotImplementedError

    def metric(self, pref, pgen):
        raise NotImplementedError

def average_agg_tanimoto(stock_vecs,
                         gen_vecs,
                         batch_size=5000,
                         agg='max',
                         device='cpu',
                         p=1):
    """
    For each molecule in gen_vecs finds closest molecule in stock_vecs.
    Returns average tanimoto score for between these molecules
    Parameters:
        stock_vecs: numpy array <n_vectors x dim>
        gen_vecs: numpy array <n_vectors' x dim>
        agg: max or mean
        p: power for averaging: (mean x^p)^(1/p)
    """
    assert agg in ['max', 'mean'], "Can aggregate only max or mean"
    agg_tanimoto = np.zeros(len(gen_vecs))
    total = np.zeros(len(gen_vecs))
    for j in range(0, stock_vecs.shape[0], batch_size):
        x_stock = torch.tensor(stock_vecs[j:j + batch_size]).to(device).float()
        for i in range(0, gen_vecs.shape[0], batch_size):
            y_gen = torch.tensor(gen_vecs[i:i + batch_size]).to(device).float()
            y_gen = y_gen.transpose(0, 1)
            tp = torch.mm(x_stock, y_gen)
            jac = (tp / (x_stock.sum(1, keepdim=True) +
                         y_gen.sum(0, keepdim=True) - tp)).cpu().numpy()
            jac[np.isnan(jac)] = 1
            if p != 1:
                jac = jac**p
            if agg == 'max':
                agg_tanimoto[i:i + y_gen.shape[1]] = np.maximum(
                    agg_tanimoto[i:i + y_gen.shape[1]], jac.max(0))
            elif agg == 'mean':
                agg_tanimoto[i:i + y_gen.shape[1]] += jac.sum(0)
                total[i:i + y_gen.shape[1]] += jac.shape[0]
    if agg == 'mean':
        agg_tanimoto /= total
    if p != 1:
        agg_tanimoto = (agg_tanimoto)**(1 / p)
    novelty = np.count_nonzero(agg_tanimoto != 1) / len(agg_tanimoto)
    return np.mean(agg_tanimoto), novelty

class SNNMetric(Metric):
    """
    Computes average max similarities of gen SMILES to ref SMILES
    """

    def __init__(self, fp_type='morgan', **kwargs):
        self.fp_type = fp_type
        super().__init__(**kwargs)

    def precalc(self, mols):
        return {
            'fps': fingerprints(mols, n_jobs=self.n_jobs, fp_type=self.fp_type)
        }

    def metric(self, pref, pgen):
        return average_agg_tanimoto(pref['fps'],
                                    pgen['fps'],
                                    device=self.device)

def cos_similarity(ref_counts, gen_counts):
    """
    Computes cosine similarity between
     dictionaries of form {name: count}. Non-present
     elements are considered zero:
     sim = <r, g> / ||r|| / ||g||
    """
    if len(ref_counts) == 0 or len(gen_counts) == 0:
        return np.nan
    keys = np.unique(list(ref_counts.keys()) + list(gen_counts.keys()))
    ref_vec = np.array([ref_counts.get(k, 0) for k in keys])
    gen_vec = np.array([gen_counts.get(k, 0) for k in keys])
    return 1 - cos_distance(ref_vec, gen_vec)

class FragMetric(Metric):

    def precalc(self, mols):
        return {'frag': compute_fragments(mols, n_jobs=self.n_jobs)}

    def metric(self, pref, pgen):
        return cos_similarity(pref['frag'], pgen['frag'])

class ScafMetric(Metric):

    def precalc(self, mols):
        return {'scaf': compute_scaffolds(mols, n_jobs=self.n_jobs)}

    def metric(self, pref, pgen):
        return cos_similarity(pref['scaf'], pgen['scaf'])

class WassersteinMetric(Metric):

    def __init__(self, func=None, **kwargs):
        self.func = func
        super().__init__(**kwargs)

    def precalc(self, mols):
        if self.func is not None:
            values = mapper(self.n_jobs)(self.func, mols)
        else:
            values = mols
        return {'values': values}

    def metric(self, pref, pgen):
        return wasserstein_distance(pref['values'], pgen['values'])

if __name__ == "__main__":
    source = '../Data/'
    dest = 'KLdiv/'
    name = 'PAPYRUS_200_standardized'
    df = pd.read_csv(f"{source}{name}.csv", usecols=['STD_SMILES'])
    train = df.sample(100000, random_state=42).STD_SMILES.tolist()

    cases = ['RNN', 'RNN_target', 'VAE', 'GAN']

    fixed = [
        '../generated/multi/transformer_multiple_12_PAPYRUS_200_16_3_rnn_errors_200_M_fixed.csv',
        '../generated/multi/transformer_multiple_12_PAPYRUS_200_16_3_rl_errors_200_M_fixed.csv',
        '../generated/multi/transformer_multiple_12_PAPYRUS_200_16_3_vae_errors_200_M_fixed.csv',
        '../generated/multi/transformer_multiple_12_PAPYRUS_200_16_3_gan_ckpt100_M_errors_200_fixed.csv'
    ]
    generated = [
        '../generated/rnn_valid.csv', '../generated/rl_valid.csv',
        '../generated/vae_valid.csv', '../generated/gan_ckpt100_M_valid.csv'
    ]

    df_ft = pd.DataFrame()
    df_fg = pd.DataFrame()
    df_gt = pd.DataFrame()
    for i, case in enumerate(cases):
        # compare fixed to train
        df_fixed = pd.read_csv(fixed[i], usecols=['CORRECT']).dropna()
        fix = df_fixed.sample(10000, random_state=42).CORRECT.tolist()
        dict_metrics_ft = get_some_metrics(gen=fix, test=train)
        if case != 'RNN_target':
            df_ft = pd.concat(
                [df_ft, pd.DataFrame(dict_metrics_ft, index=[i])])

        file = open(f"tanimoto/{case}_test_fixed_train.txt", "w")

        for key, value in dict_metrics_ft.items():

            file.write('%s: %.4f\n' % (key, value))

        file.close()

        # compare fixed to generated (correct-in-one-go)
        df_gen = pd.read_csv(generated[i], usecols=['SMILES'])
        gen = df_gen.sample(100000, random_state=42).SMILES.tolist()
        dict_metrics_fg = get_some_metrics(gen=fix, test=gen)
        if case != 'RNN_target':
            df_fg = pd.concat(
                [df_fg, pd.DataFrame(dict_metrics_fg, index=[i])])

        file = open(f"tanimoto/{case}_fixed_gen.txt", "w")

        for key, value in dict_metrics_fg.items():

            file.write('%s: %.4f\n' % (key, value))

        file.close()

        # compare generated (correct-in-one-go) to train
        gen = df_gen.sample(10000, random_state=42).SMILES.tolist()
        dict_metrics_gt = get_some_metrics(gen=gen, test=train)
        if case != 'RNN_target':
            df_gt = pd.concat(
                [df_gt, pd.DataFrame(dict_metrics_gt, index=[i])])
        file = open(f"tanimoto/{case}_gen_train.txt", "w")

        for key, value in dict_metrics_gt.items():

            file.write('%s: %.4f\n' % (key, value))

        file.close()

    names = ['fixed_train', 'fixed_generated', 'generated_train']
    for i, df in enumerate([df_ft, df_fg, df_gt]):
        df.to_csv(f'{i}.csv')
        print(df)
        file = open(f"tanimoto/{names[i]}_mean_std.txt", "a")

        for key, value in dict_metrics_gt.items():
            print(df[key].mean)
            file.write('%s: %.2f ± %.3f\n' %
                       (key, df[key].mean(), df[key].std()))

        file.close()


class queue:

    def __init__(self):
        self.array = []

    def enqueue(self, data):
        self.array.append(data)

    def dequeue(self):
        print(self.array.pop(0))

    def traverse(self):

        for i in self.array:
            print(i, end=" ")

q = queue()

q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
q.enqueue(40)
q.enqueue(50)

q.traverse()

print()
q.dequeue()
q.dequeue()
q.dequeue()

q.traverse()


from itertools import combinations

n = int(input())
A = input().split()
k = int(input())
list1 = list(A)
list2 = []
for i in range(1, n+1):
    list2.append(i)
t = len(list(combinations(list2,k)))

for i in range(1,n+1):
    if list1[i-1] == "a":
        list2.remove(i)

v = len(list(combinations(list2,k)))
print("{0:.3}".format((t-v)/t))


# Import Libraries and Modules
import sys
import argparse
from pathlib import Path
import wandb
import torch
import torch.nn as nn
from torch.utils.data.dataloader import DataLoader
import torchvision.transforms as transforms
from model import ResNet
from torchvision.datasets import ImageFolder
import optuna
# from optuna.visualization import plot_optimization_history
# from optuna.visualization import plot_intermediate_values
import os

if not os.path.exists("Images"):
    os.mkdir("Images")

project_dir = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(project_dir / 'src/data'))
from make_dataset import main as dataset  # noqa: E402

def objective(trial):
    project_dir = str(Path(__file__).resolve().parents[2])
    processed_dir = project_dir + '/data/processed'
    train_dir = processed_dir + '/Train'
    # test_dir = processed_dir + '/Test'
    val_dir = processed_dir + '/Validation'

    lr = trial.suggest_discrete_uniform('lr', 1e-6, 1e-0, 1e-6)
    batch_size = int(trial.suggest_discrete_uniform('batch_size', 5, 30, 5))
    # batch_normalize = trial.suggest_categorical('batch_normalize', ['True', 'False'])
    # activation_function = trial.suggest_categorical('activations', [nn.ReLU, nn.Tanh, nn.RReLU, nn.LeakyReLU, nn.ELU])

    # if batch_normalize == False:
    transformations = transforms.Compose([transforms.Resize((256, 256)), transforms.ToTensor()])
    train_set = ImageFolder(train_dir, transform=transformations)
    # test_set = ImageFolder(test_dir, transform=transformations)
    val_set = ImageFolder(val_dir, transform=transformations)
    # else:
    #     transformations = transforms.Normalize([transforms.Resize((256, 256)), transforms.ToTensor()])
    #     train_set = ImageFolder(train_dir, transform=transformations)
    #     test_set = ImageFolder(test_dir, transform=transformations)
    #     val_set = ImageFolder(val_dir, transform=transformations)

    # DATALOADERS
    train_dl = DataLoader(train_set, batch_size, shuffle=True, num_workers=4, pin_memory=True)
    val_dl = DataLoader(val_set, batch_size * 2, shuffle=True, num_workers=4, pin_memory=True)
    if torch.cuda.is_available():
        device = torch.device('cuda')
    else:
        device = torch.device('cpu')

    model = ResNet()
    model.to(device)
    print(device)

    criterion = nn.CrossEntropyLoss()

    optimizer = torch.optim.Adam(model.parameters(), lr=lr)
    epochs = 10
    for epoch in range(epochs):

        train_accuracy = 0
        model.train()

        for (counter, (images, labels)) in enumerate(train_dl):
            images, labels = images.to(device), labels.to(device)
            output = model(images)
            _, predictions = torch.max(output, dim=1)
            loss = criterion(output, labels)
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
            train_acc = torch.tensor(torch.sum(predictions == labels).item() / len(predictions))
            train_accuracy += train_acc
        # epoch_train_acc = train_accuracy.item() / (counter + 1)

        with torch.no_grad():
            val_accuracy = 0
            # class_acc = {}
            # correct_pred_list = [0 for _ in range(6)]
            # total_pred_list = [0 for _ in range(6)]
            model.eval()
            for (counter, (images, labels)) in enumerate(val_dl):
                images, labels = images.to(device), labels.to(device)
                outputs = model(images)
                _, predictions = torch.max(outputs, dim=1)
                val_acc = torch.tensor(torch.sum(predictions == labels).item() / len(predictions))
                val_accuracy += val_acc

            epoch_val_acc = val_accuracy.item() / (counter + 1)

    return epoch_val_acc

class TrainOREvaluate(object):
    def __init__(self):
        parser = argparse.ArgumentParser(
            description="Script for either training or evaluating",
            usage="python train_model.py <command>"
        )
        parser.add_argument("command", help="Subcommand to run")
        args = parser.parse_args(sys.argv[1:2])
        if not hasattr(self, args.command):
            print('Unrecognized command')
            parser.print_help()
            exit(1)
        getattr(self, args.command)()

    def train(self):
        print("Training day and night")
        # Arguments
        parser = argparse.ArgumentParser(description='Training arguments')
        parser.add_argument('--lr', default=5.5e-5)
        parser.add_argument('--batch_size', default=32)
        parser.add_argument('--num_epochs', type=int, default=10)
        args = parser.parse_args(sys.argv[2:])
        print(args)
        # Load Data
        train_set, test_set, val_set = dataset()
        classes = ['Glass', 'Paper', 'Cardboard', 'Plastic', 'Metal', 'Trash']
        # Set Device and Model Configurations
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        print(device)
        model = ResNet()
        model.to(device)
        criterion = nn.CrossEntropyLoss()
        optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
        train_dl = DataLoader(train_set, args.batch_size, shuffle=True, num_workers=4, pin_memory=True)
        val_dl = DataLoader(val_set, args.batch_size * 2, shuffle=True, num_workers=4, pin_memory=True)
        # Initialize wandb
        wandb.login()
        wandb.init(project='testing', config=args, dir=str(project_dir.joinpath('./reports')))
        wandb.watch(model, log_freq=100)
        for epoch in range(args.num_epochs):
            # Training
            train_accuracy = 0
            model.train()
            for (counter, (images, labels)) in enumerate(train_dl):
                images, labels = images.to(device), labels.to(device)
                output = model(images)
                _, predictions = torch.max(output, dim=1)
                loss = criterion(output, labels)
                loss.backward()
                optimizer.step()
                optimizer.zero_grad()
                train_acc = torch.tensor(torch.sum(predictions == labels).item() / len(predictions))
                wandb.log({"Training Accuracy (per batch)": train_acc})
                wandb.log({"Training Loss": loss})
                train_accuracy += train_acc
            epoch_train_acc = train_accuracy.item() / (counter + 1)
            wandb.log({"Training Accuracy (per epoch)": epoch_train_acc})
            print('(Epoch {}) Training accuracy: {:.2f}%'.format(epoch + 1, epoch_train_acc * 100))
            # Evaluation
            with torch.no_grad():
                val_accuracy = 0
                class_acc = {}
                correct_pred_list = [0 for _ in range(6)]
                total_pred_list = [0 for _ in range(6)]
                model.eval()
                for (counter, (images, labels)) in enumerate(val_dl):
                    images, labels = images.to(device), labels.to(device)
                    outputs = model(images)
                    _, predictions = torch.max(outputs, dim=1)
                    val_loss = criterion(outputs, labels)
                    val_acc = torch.tensor(torch.sum(predictions == labels).item() / len(predictions))
                    wandb.log({"Validation Accuracy (per batch)": val_acc})
                    wandb.log({"Validation Loss": val_loss})
                    val_accuracy += val_acc
                    for label, prediction in zip(labels, predictions):
                        if label == prediction:
                            correct_pred_list[label] += 1
                        total_pred_list[label] += 1
                epoch_val_acc = val_accuracy.item() / (counter + 1)
                wandb.log({"Validation Accuracy (per epoch)": epoch_val_acc})
                print('(Epoch {}) Validation accuracy: {:.2f}%'.format(epoch + 1, epoch_val_acc * 100))
            for i in range(len(classes)):
                print('Accuracy of %5s : %.2f %%' % (classes[i], 100 * correct_pred_list[i] / total_pred_list[i]))
                class_acc["Accuracy of %5s" % (classes[i])] = 100 * correct_pred_list[i] / total_pred_list[i]
            wandb.log(class_acc)
            torch.save(model.state_dict(),
                       project_dir.joinpath('models/model' + str(epoch) + '.pth'))

    def evaluate(self):
        print("Evaluating until hitting the ceiling")
        # Arguments
        parser = argparse.ArgumentParser(description='Training arguments')
        parser.add_argument('--load_model_from', default='model0')
        parser.add_argument('--batch_size', default=64)
        args = parser.parse_args(sys.argv[2:])
        print(args)
        # Load Model
        model_path = str(project_dir.joinpath('./models')) + '/' + args.load_model_from + '.pth'
        # Load Data
        train_set, test_set, val_set = dataset()
        # Set Device and Model Configurations
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        print(device)
        model = ResNet()
        model.to(device)
        test_dl = DataLoader(test_set, args.batch_size * 2, shuffle=True, num_workers=4, pin_memory=True)
        if torch.cuda.is_available():
            dict_ = torch.load(model_path)
        else:
            dict_ = torch.load(model_path, map_location='cpu')
        model.load_state_dict(dict_)
        with torch.no_grad():
            test_accuracy = 0
            model.eval()
            for (counter, (images, labels)) in enumerate(test_dl):
                images, labels = images.to(device), labels.to(device)
                outputs = model(images)
                _, predictions = torch.max(outputs, dim=1)
                test_acc = torch.tensor(torch.sum(predictions == labels).item() / len(predictions))
                test_accuracy += test_acc
            accuracy = test_accuracy.item() / (counter + 1)
            print('Test accuracy: {:.2f}%'.format(accuracy * 100))

if __name__ == '__main__':
    sampler = optuna.samplers.TPESampler(seed=10)
    study = optuna.create_study(direction="maximize", sampler=sampler,
                                pruner=optuna.pruners.MedianPruner(n_startup_trials=5, n_warmup_steps=30, interval_steps=10))
    study.optimize(objective, n_trials=5)
    fig = optuna.visualization.plot_optimization_history(study)
    fig.write_image("Images/fig1.png")
    # fig.show()

    fig = optuna.visualization.plot_intermediate_values(study)
    fig.write_image("Images/fig2.png")
    # fig.show()
    # TrainOREvaluate()


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import random
import time

options = webdriver.ChromeOptions()         #시스템 오류를 위해 삽입한구문
options.add_experimental_option("excludeSwitches", ["enable-logging"])   #시스템 오류를 위해 삽입한구문
browser = webdriver.Chrome(options=options)  #시스템 오류를 위해 삽입한구문

# 1 네이버 로그인
browser.get('https://naver.com')
browser.maximize_window()   #창의 크기 맥시멈
action = ActionChains(browser)  #키다운 할때 필요한 부분을 액션으로 저장함.

# 2 네이버 로그인 버튼 찾기 및 클릭.
browser.find_element_by_class_name("link_login").click()
time.sleep(random.uniform(1,3))
# 3네이버 아이디 및 패스워드 창
time.sleep(3)
browser.find_element_by_id("id").send_keys("bestbox1111")

# action.send_keys(Keys.TAB).perform()
time.sleep(3)
browser.find_element_by_id("pw").send_keys("k9910k057")
time.sleep(3)

# 4 로그인 버튼 클릭
browser.find_element_by_id("log.login").click()


import numpy
from gnuradio import gr
import pmt

import datetime

class print_timestamp(gr.basic_block):
    """
    docstring for block print_timestamp
    """
    def __init__(self, tstamp_format=''):
        gr.basic_block.__init__(self,
            name="swap_crc",
            in_sig=[],
            out_sig=[])

        self.message_port_register_in(pmt.intern('in'))
        self.set_msg_handler(pmt.intern('in'), self.handle_msg)
        self.message_port_register_out(pmt.intern('out'))

        self.tstamp_format = tstamp_format

    def handle_msg(self, msg_pmt):
        if self.tstamp_format:
            timestamp = datetime.datetime.utcnow()
            print(timestamp.strftime(self.tstamp_format))

        self.message_port_pub(pmt.intern('out'), msg_pmt)


from FDtree import FDTree
from pandas import *
import time
import copy
def violated(a,b,invalid_fds):
    global listofcolumns
    global atts_num
    dis = [] #值不同的属性的序号
    arg = [] #值相同的属性的序号
    for x in range(0,atts_num):
        if a[x] == b[x]:
            arg.append(x)
        else:
            dis.append(x)

    for a in dis:
        rhs = []
        rhs.append(a)
        invalid_fds.add(arg,rhs) #不需要考虑是否存在重复，因为add本身就不会重复添加，不过是否要考虑存在general?

#解决NCOVER冗余的问题
def Ncover_refine(fdtree):
    fds = list(fdtree.read_fds())
    for fd in fds:
        for rhs in fd[1]: #提取出单个的右边属性，因为get general函数需要
            general_lhss =  list(fdtree.get_fd_and_generals(list(fd[0]),rhs))
            if fd[0] in general_lhss : general_lhss.remove(fd[0])
            if(general_lhss):
                for lhs in general_lhss:
                    fdtree.remove(lhs,rhs)

#NCOVER和最后要输出DEPS不同，DEPS里面要的是最小函数依赖，如果新加的里面有更细分的，就舍去，而NCOVER要的是最细分的依赖，如果加的时候存在更宽泛的fd，需要删去general的
def negative_cover(relation):
    global atts_num
    NCOVER = FDTree(atts_num)#初始化一棵invalid_fdtree，当前只有[]->all attributes
    for i in range(0,len(relation)):
        for j in range(i+1,len(relation)):
            violated(relation[i],relation[j],NCOVER)
    Ncover_refine(NCOVER)
    return NCOVER

#初始化一棵[]->[all attributes]的fdtree
def initialise():
    global atts_num
    deps = FDTree(atts_num)
    deps.add([],range(atts_num))
    return deps

#凑新的lhs是在D_lhs上只加一个属性，并且加完之后还是要检查是否已经不在entail ND了
def specialise(fdtree, D , ND_lhs):#是根据D的lhs来加一个属性，不是ND的lhs
    att_num = 4
    for i in range(att_num):
        if ((i not in ND_lhs) and (i != D[1])):
            lhs = set(D[0][:])  # 把ND的lhs提出来
            lhs.add(i)  # 加一个新属性构成新的lhs，并且用set保证升序
            rhs = []
            rhs.append(D[1])
            if not fdtree.fd_has_generals(list(lhs),rhs[0]):
                fdtree.add(list(lhs), rhs)  # 不会entail ND、新的D，加入到Q中

def bottom_up(r):
    global listofcolumns
    DEPS = initialise() #初始化
    NCOVER = negative_cover(r) #ncover是一个list，里面的invalid_fd用tuple格式的({lhs},[rhs])存
    for ND in list(NCOVER.read_fds()): #ND是({lhs},[rhss])
        lhs = ND[0]
        rhss = ND[1]
        for rhs in rhss:#rhss要拆开，因为get general函数要求右手边是单个属性
           tmp = copy.deepcopy(DEPS) #拷贝一个对象
           D_lhss = list(DEPS.get_fd_and_generals(list(lhs),rhs)) #找到所有能entail ND的D，返回的是一个list，里面都是set格式的lhs
           for D in D_lhss:
               tmp.remove(D,rhs)
               specialise(tmp,(list(D),rhs),lhs)
               DEPS = copy.deepcopy(tmp)
    return DEPS

def index_to_name(res):
    global listofcolumns
    result = []
    for fd in res:
       lhs_n = []
       for att in fd[0]:
           lhs_n.append(listofcolumns[att])
       for rhs in fd[1]:
           result.append((lhs_n,listofcolumns[rhs]))
    return result

infile = open('abalone.csv')
data = read_csv(infile)
ntuples = len(data.index) #元组数量
listofcolumns = data.columns.tolist() #属性列表,是index格式,再转list
atts_num = len(listofcolumns) #属性个数
print("ncover:",list(negative_cover(data.values).read_fds()))
t0 = time.time()
result = bottom_up(data.values)
result = list(result.read_fds())#转成list，此时属性都还是序号
result = index_to_name(result)
print("num of fds:",result.__len__())
print(result)
print(format(time.time() - t0))
#print_result(result)


from distutils.command.upload import upload
from email.policy import default
from pickle import TRUE
from django.db import models
from django.forms import CharField, FileField
from django.utils import timezone
from django.contrib.auth.models import User
from django_countries.fields import CountryField
from multiselectfield import MultiSelectField
from django import forms
from ckeditor.fields import RichTextField

#CHOICES
PROGRAMME_LEVEL = [
    ('1', '1'),
    ('2', '2'),
    ('3', '3'),
    ('4', '4'),
    ('5', '5'),
    ('6', '6'),
    ('7', '7'),
    ('8', '8'),
    ('9', '9'),
    ('10', '10'),
    ('11', '11'),
]
TERTIARY_AUTHORITY = [
    ('NQA', 'Namibia Qualification Authority'),
]
MODE_OF_STUDY = [
    ('Full-time', 'Full-time'),
    ('Part-time', 'Part-time'),
    ('Online', 'Online'),
]

COURSE_CATEGORY = [
    ('Shortcourse', 'Shortcourse'),
    ('Undergraduate', 'Undergraduate'),
    ('Postgraduate', 'Postgraduate'),
]

BASE_ON_LEVEL = [('Grade-11', 'Grade-11'), ('Grade-12', 'Grade-12'),
                 ('Mature-age', 'Mature age'),
                 ('Other-qualitication', 'Other Qualitication')]

STATUS_OF_APPLICATION = [
    ('In progress', 'In progress'),
    ('Pending', 'Pending'),
    ('Rejected', 'Rejected'),
    ('Approved', 'Approved'),
    ('Cancelled', 'Cancelled'),
]

GENDER = [
    ('Male', 'Male'),
    ('Female', 'Female'),
]
PERMIT_TYPE = [
    ('Study', 'Study'),
    ('Work', 'Work'),
    ('Diplomatic', 'Diplomatic'),
    ('Tourism', 'Tourism'),
]
CONDITIONAL_ANSWER = [
    ('YES', 'YES'),
    ('NO', 'NO'),
    ('MAYBE', 'MAYBE'),
]
CONDITIONAL_ANSWER_BINARY = [
    ('NO', 'NO'),
    ('YES', 'YES'),
]
TITLE = [
    ('MR', 'MR'),
    ('MS', 'MS'),
    ('MRS', 'MRS'),
    ('DR', 'DR'),
]

MARITAL_STATUS = [
    ('Single', 'Single'),
    ('Married', 'Married'),
    ('Divorsed', 'Divorsed'),
    ('Separated', 'Separated'),
    ('Widowed', 'Widowed'),
]

RELATIONSHIP_TYPE = [
    ('Parent', 'Parent'),
    ('Spouse', 'Spouse'),
    ('Guardian', 'Guardian'),
]

SPONSORSHIP_TYPE = [
    ('Self Sponsored', 'Self Sponsored'),
    ('Sponsored by a Third-party', 'Sponsored by a Third-party'),
]

NAMIBIAN_REGION = [
    ('Erongo', 'Erongo'),
    ('Hardap', 'Hardap'),
    ('Karas', 'Karas'),
    ('Khomas', 'Khomas'),
    ('Kunene', 'Kunene'),
    ('Kavango East', 'Kavango East'),
    ('Kavango West', 'Kavango West'),
    ('Otjozondjupa', 'Otjozondjupa'),
    ('Oshana', 'Oshana'),
    ('Oshikoto', 'Oshikoto'),
    ('Omusati', 'Omusati'),
    ('Zambezi', 'Zambezi'),
    ('Omaheke', 'Omaheke'),
    ('Ohangwena', 'Ohangwena'),
]

LANGUAGE = [
    ('English', 'English'),
    ('Oshiherero', 'Oshiherero'),
    ('Damara / Nama', 'Damara / Nama'),
    ('AfriKaans', 'AfriKaans'),
    ('Portuguese', 'Portuguese'),
    ('French', 'French'),
    ('Spanish', 'Spanish'),
    ('German', 'German'),
    ('Russian', 'Russian'),
    ('Chinise / Mandarine', 'Chinise / Mandarine'),
    ('Other', 'Other'),
]

#UNIVERSITY TABLES
class Faculty(models.Model):
    dean = models.ForeignKey(User,
                             on_delete=models.CASCADE,
                             blank=True,
                             null=True)
    name = models.CharField(max_length=100, blank=True, null=True)
    creation_date = models.DateTimeField(auto_now_add=True,
                                         blank=True,
                                         null=True)
    updation_date = models.DateTimeField(auto_now=True, blank=True, null=True)

    def __str__(self):
        return str(self.name)

class Programme(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)
    level = models.CharField(max_length=3,
                             choices=PROGRAMME_LEVEL,
                             blank=True,
                             null=True)
    authority = models.CharField(max_length=50,
                                 choices=TERTIARY_AUTHORITY,
                                 blank=True,
                                 null=True)

    def __str__(self):
        return str(self.name) + " " + str(self.authority) + " (" + str(
            self.level) + ")"

class Course(models.Model):
    faculty = models.ForeignKey(Faculty, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, blank=True, null=True)
    course_code = models.CharField(max_length=10, blank=True, null=True)
    level = models.ForeignKey(Programme,
                              on_delete=models.SET_NULL,
                              max_length=100,
                              blank=True,
                              null=True)
    mode_of_study = MultiSelectField(choices=MODE_OF_STUDY,
                                     blank=True,
                                     null=True)
    tuition_fee = models.DecimalField(max_digits=10,
                                      decimal_places=2,
                                      blank=True,
                                      null=True)
    credits = models.PositiveIntegerField(blank=True, null=True)
    number_years = models.PositiveIntegerField(blank=True, null=True)
    creation_date = models.DateTimeField(auto_now_add=True,
                                         blank=True,
                                         null=True)
    updation_date = models.DateTimeField(auto_now=True, blank=True, null=True)

    def __str__(self):
        return str(self.name)

class Secondary_course(models.Model):
    course = models.OneToOneField(Course, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.course.name}'

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

class Campus(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)
    campus_code = models.CharField(max_length=10, blank=True, null=True)
    contact = models.CharField(max_length=10, blank=True, null=True)
    email = models.EmailField(max_length=50, blank=True, null=True)
    country = CountryField(blank_label='(select country)', default="NA")
    town = models.CharField(max_length=50, blank=True, null=True)
    address = models.TextField(max_length=200, blank=True, null=True)

    creation_date = models.DateTimeField(auto_now_add=True,
                                         blank=True,
                                         null=True)
    updation_date = models.DateTimeField(auto_now=True, blank=True, null=True)

    def __str__(self):
        return str(self.name)

class Subject(models.Model):
    lecturer = models.ForeignKey(User,
                                 on_delete=models.SET_NULL,
                                 default="unavailable",
                                 blank=True,
                                 null=True)
    faculty = models.ForeignKey(Faculty,
                                on_delete=models.CASCADE,
                                default="unavailable",
                                blank=True,
                                null=True)
    name = models.CharField(max_length=100, blank=True, null=True)
    subject_code = models.CharField(max_length=50, blank=True, null=True)
    level = models.PositiveIntegerField(blank=True, null=True)
    credits = models.PositiveIntegerField(blank=True, null=True)
    subject_outline = models.TextField(max_length=1000, blank=True, null=True)

    def __str__(self):
        return str(self.subject_code) + " - " + str(self.name)

#APPLICATION TABLES
class Application(models.Model):
    owner = models.ForeignKey(User,
                              on_delete=models.CASCADE,
                              blank=True,
                              null=True)
    programme = models.ForeignKey(Programme,
                                  on_delete=models.SET('deleted'),
                                  blank=True,
                                  null=True)
    course_first_choice = models.ForeignKey(Course,
                                            on_delete=models.SET('deleted'),
                                            blank=True,
                                            null=True)
    course_second_choice = models.ForeignKey(Secondary_course,
                                             on_delete=models.SET('deleted'),
                                             blank=True,
                                             null=True)

    category = MultiSelectField(max_length=50,
                                choices=COURSE_CATEGORY,
                                blank=True,
                                null=True)
    prefered_campus = models.ForeignKey(Campus,
                                        on_delete=models.SET('deleted'),
                                        blank=True,
                                        null=True)
    based_on_level = models.CharField(max_length=50,
                                      choices=BASE_ON_LEVEL,
                                      blank=True,
                                      null=True)
    other_level = models.CharField(max_length=100, blank=True, null=True)
    current_step = models.SmallIntegerField(default=0, blank=True, null=True)

    prefered_period = models.CharField(
        max_length=50,
        choices=MODE_OF_STUDY,
        default='Full-time',
    )

    status = models.CharField(
        max_length=50,
        choices=STATUS_OF_APPLICATION,
        default=STATUS_OF_APPLICATION[0],
    )
    creation_date = models.DateTimeField(auto_now_add=True,
                                         blank=True,
                                         null=True)
    submition_date = models.DateTimeField(auto_now=True, blank=True, null=True)

    def __str__(self):
        return "owner: " + str(self.owner) + " | programme: " + str(
            self.category) + "   " + str(self.status)

class Profile(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    nationality = CountryField(blank_label='(select country)', default="NA")
    namibian_region = models.CharField(choices=NAMIBIAN_REGION,
                                       default=NAMIBIAN_REGION[0],
                                       max_length=50,
                                       null=True)
    title = models.CharField(
        choices=TITLE,
        default=TITLE[0],
        max_length=10,
    )
    gender = models.CharField(
        choices=GENDER,
        default=GENDER[0],
        max_length=10,
    )
    full_name = models.CharField(max_length=100, blank=True, null=True)
    surname = models.CharField(max_length=100, blank=True, null=True)

    date_of_birth = models.DateField(blank=True, null=True)
    marital_status = models.CharField(
        choices=MARITAL_STATUS,
        default=MARITAL_STATUS[0],
        max_length=10,
    )
    id_number = models.PositiveIntegerField(blank=True, null=True)
    passport_number = models.CharField(max_length=20, blank=True, null=True)
    passport_expiry_date = models.DateField(blank=True, null=True)
    permit_number = models.PositiveIntegerField(blank=True, null=True)
    permit_type = models.CharField(
        choices=PERMIT_TYPE,
        default=PERMIT_TYPE[0],
        max_length=30,
    )
    permit_expiry_date = models.DateField(blank=True, null=True)
    has_medical_condition = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default='NO',
        max_length=20,
    )
    has_medical_needs = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default='NO',
        max_length=20,
    )
    medical_condition_description = models.TextField(max_length=500,
                                                     blank=True,
                                                     null=True)

    def __str__(self):
        return str(self.application)

class Contact(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    cellphone_number_1 = models.PositiveIntegerField(blank=True, null=True)
    cellphone_number_2 = models.PositiveIntegerField(blank=True, null=True)
    telephone = models.IntegerField(blank=True, null=True)
    email = models.EmailField(max_length=50, blank=True, null=True)
    namibia_postal_address = models.CharField(max_length=15,
                                              blank=True,
                                              null=True)
    namibia_residential_address = models.TextField(max_length=100,
                                                   blank=True,
                                                   null=True)
    origin_postal_address = models.CharField(max_length=15,
                                             blank=True,
                                             null=True)
    origin_residential_address = models.TextField(max_length=100,
                                                  blank=True,
                                                  null=True)

    def __str__(self):
        return str(self.application)

class Kin(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    kin_title = models.CharField(
        choices=TITLE,
        default=TITLE[0],
        max_length=10,
    )
    first_name = models.CharField(max_length=50, blank=True, null=True)
    last_name = models.CharField(max_length=50, blank=True, null=True)
    kin_id_number = models.CharField(max_length=50, blank=True, null=True)
    relationship_type = models.CharField(
        choices=RELATIONSHIP_TYPE,
        default=RELATIONSHIP_TYPE[0],
        max_length=15,
    )
    kin_email = models.EmailField(max_length=50, blank=True, null=True)
    kin_cellphone_number = models.PositiveIntegerField(blank=True, null=True)
    kin_telephone = models.PositiveIntegerField(blank=True, null=True)

    kin_residential_address = models.TextField(max_length=100,
                                               blank=True,
                                               null=True)
    kin_postal_address = models.CharField(max_length=15, blank=True, null=True)
    kin_occupation = models.CharField(max_length=50, blank=True, null=True)
    Work_telephone = models.PositiveIntegerField(blank=True, null=True)

    def __str__(self):
        return str(self.application)

class Employer(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    employer_name = models.CharField(max_length=50, blank=True, null=True)
    occupation = models.CharField(max_length=50, blank=True, null=True)
    employer_telephone = models.PositiveIntegerField(blank=True, null=True)
    employer_email = models.EmailField(max_length=50, blank=True, null=True)
    start_date = models.DateField(blank=True, null=True)
    end_date = models.DateField(blank=True, null=True)
    duties = models.TextField(blank=True, null=True)

    def __str__(self):
        return str(self.application)

class Outstanding_result(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    has_out_standing_exam = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default='NO',
        max_length=20,
    )
    out_standing_exam = models.CharField(max_length=50, blank=True, null=True)
    out_standing_exam_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return str(self.application)

class Language(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    school_language = models.CharField(
        choices=LANGUAGE,
        default=LANGUAGE[0],
        max_length=50,
    )
    home_language = models.CharField(
        choices=LANGUAGE,
        default=LANGUAGE[0],
        max_length=50,
    )
    has_english_course = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default="NO",
        max_length=20,
    )
    english_course = models.CharField(max_length=50, blank=True, null=True)
    applying_english_course = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default="NO",
        max_length=20,
    )

    def __str__(self):
        return str(self.application)

class Post_acadmic_qualification(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    has_past_qualification = models.CharField(
        choices=CONDITIONAL_ANSWER_BINARY,
        default='NO',
        max_length=20,
    )
    institution_name = models.CharField(max_length=50, blank=True, null=True)
    location = CountryField(blank_label='(select country)',
                            default="NA",
                            blank=True,
                            null=True)
    post_qualification = models.CharField(max_length=100,
                                          blank=True,
                                          null=True)
    year_start = models.PositiveBigIntegerField(blank=True, null=True)
    year_end = models.PositiveBigIntegerField(blank=True, null=True)

    def __str__(self):
        return str(self.application)

class School_leaving(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    school_name = models.CharField(max_length=100, blank=True, null=True)
    highest_grade = models.CharField(max_length=10, blank=True, null=True)
    exam_year = models.PositiveSmallIntegerField(blank=True, null=True)
    exam_authority = models.CharField(max_length=30, blank=True, null=True)

    def __str__(self):
        return str(self.application)

class School_leaving_subject(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    school = models.ForeignKey(School_leaving,
                               on_delete=models.CASCADE,
                               blank=True,
                               null=True)
    subject_name = models.CharField(max_length=30, blank=True, null=True)
    subject_level = models.CharField(max_length=15, blank=True, null=True)
    symbol = models.CharField(max_length=1, blank=True, null=True)
    point = models.PositiveIntegerField(blank=True, null=True)

    def __str__(self):
        return str(self.application)

class Sponsor(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       default="unavailable")
    sponsor_name = models.CharField(max_length=100, blank=True, null=True)
    sponsor_signatory_name = models.CharField(max_length=100,
                                              blank=True,
                                              null=True)
    sponsorship_type = models.CharField(
        choices=SPONSORSHIP_TYPE,
        max_length=50,
        default='Self Sponsored',
    )
    sponsor_postal_address = models.CharField(max_length=30,
                                              blank=True,
                                              null=True)
    sponsor_cellphone = models.PositiveIntegerField(blank=True, null=True)
    sponsor_telephone = models.PositiveIntegerField(blank=True, null=True)
    sponsor_email = models.EmailField(max_length=50, blank=True, null=True)
    tuition_fee = models.DecimalField(max_digits=10,
                                      decimal_places=2,
                                      blank=True,
                                      null=True)
    registration_fee = models.DecimalField(max_digits=10,
                                           decimal_places=2,
                                           blank=True,
                                           null=True)
    student_fund = models.DecimalField(max_digits=10,
                                       decimal_places=2,
                                       blank=True,
                                       null=True)

    total_fee = models.DecimalField(max_digits=10,
                                    decimal_places=2,
                                    blank=True,
                                    null=True)

    def __str__(self):
        return str(self.application)

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/<username>/<filename>
    return '{0}/application_documents/{1}'.format(
        instance.application.owner.username, filename)

class Document(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       blank=True,
                                       null=True)
    medical_documents = models.FileField(upload_to=user_directory_path,
                                         blank=True,
                                         null=True)
    certified_id_copy = models.FileField(upload_to=user_directory_path,
                                         blank=True,
                                         null=True)
    passport_photo = models.FileField(upload_to=user_directory_path,
                                      blank=True,
                                      null=True)
    evidence_of_payment = models.FileField(upload_to=user_directory_path,
                                           blank=True,
                                           null=True)
    foreign_qualification = models.FileField(upload_to=user_directory_path,
                                             blank=True,
                                             null=True)
    foreign_qualification_translation = models.FileField(
        upload_to=user_directory_path, blank=True, null=True)
    namibia_highest_qualification_copy = models.FileField(
        upload_to=user_directory_path, blank=True, null=True)
    other_documents = models.FileField(upload_to=user_directory_path,
                                       blank=True,
                                       null=True)

    def __str__(self):
        return str(self.application)

class TermsAndConditions(models.Model):
    application = models.OneToOneField(Application,
                                       on_delete=models.CASCADE,
                                       blank=True,
                                       null=True)
    title = models.CharField(max_length=200, blank=True, null=False)
    general_rule = RichTextField(blank=True, null=False)
    application_form_acknowledgement = models.BooleanField(default=False)

    def __str__(self):
        return str(self.application) + " - " + str(self.title)


"""
author: Wenyu Qiu
des: some def for the diff of func
"""
import sympy as sp

def multi_diff(func, vars):
    """ acquire diff for n-dimension func """
    dif_vect = sp.zeros(len(vars), 1)
    for i in range(len(vars)):
        tmp_dif = sp.diff(func, vars[i])
        dif_vect[i] = tmp_dif
    return dif_vect

def hessian(func, vars):
    """ for n-dimension hessian matrix, @func(spy), @variables(under spy sys) """
    hes_mat = sp.zeros(len(vars), len(vars))
    for i in range(len(vars)):
        v1 = vars[i]
        df1 = sp.diff(func, v1)
        for j in range(len(vars)):
            v2 = vars[j]
            df2 = sp.diff(df1, v2)
            hes_mat[i, j] = df2
    return hes_mat

if __name__ == '__main__':
    x1, x2 = sp.symbols('x1, x2')
    func = x1**2 + x2**2
    # print(hessian(func, [x1, x2]))
    print(multi_diff(func, [x1, x2]))


import aiohttp
from vkbottle.rule import FromMe
from vkbottle.user import Blueprint, Message

from idm_lp import const
from idm_lp.database import Database
from idm_lp.idm_api import IDMAPI
from idm_lp.logger import logger_decorator
from idm_lp.utils import edit_message

user = Blueprint(
    name='set_db_blueprint'
)

@user.on.message_handler(FromMe(), text="<prefix:service_prefix> получить бд")
@logger_decorator
async def set_db_wrapper(message: Message, **kwargs):
    db = Database.get_current()
    try:
        response = await IDMAPI.get_current().get_lp_info(db.tokens[0])
    except Exception as ex:
        await edit_message(
            message,
            f"⚠ Ошибка: {ex}"
        )
        return
    new_db = db.load_from_server(response['config'])
    new_db.secret_code = response['secret_code']
    new_db.ru_captcha_key = response['ru_captcha_key']
    Database.set_current(new_db)
    new_db.save()
    await edit_message(
        message,
        "✅ Конфигурация успешно обновлена с сервера"
    )


import json
import redis

r = redis.Redis(host='localhost', port=22772)
my_dict = {"name": "John", "age": 30, "city": "New York"}
outDict = {'urlKey': my_dict}  # 改为使用冒号分隔键和值
# 序列化成JSON字符串
json_string = json.dumps(outDict)

# 将JSON字符串存储到Redis中
r.set("my_dict", json_string)

# 从Redis中读取JSON字符串
json_string_redis = r.get("my_dict")

# 反序列化成Python对象
my_dict_redis = json.loads(json_string_redis)
print(my_dict_redis)


from fbs import fbs_subscribe, fbs_login, fbs_connect
import time
import websocket
import flatbuffers
import Hoevo
import Hoevo.VehicleInfo
import Hoevo.Any
import Hoevo.Msg
import Hoevo.Payload
import Hoevo.PayloadType
import Hoevo.Login
import Hoevo.Project
import Hoevo.PUBLISH
import Hoevo.Role
import Hoevo.QoS
import Hoevo.Flag

def set_vehicle_info_to_data():
    data = {
        'uuid': "test_data",
        'player_id': "test_data",
        'device_id': "test_data",
        'bEngineStart': False,
        'bHandBrake': False,
        'ClutchIntensity': 0.5,
        'BrakePedalIntensity': 1,
        'ThrottleIntensity': 0.5,
        'bSafetyBelt': False,
        'CurrentGear': 1,
        'bAddGearByDegrees': False,
        'bSubGearByDegrees': False,
        'CorneringLampState': 1,
        'bHorn': False,
        'bDoubleFlash': False,
        'SteeringWheelAngle': 0.5,
        'Speed': 0.0,
        'TrainingProgram': 304,
        'TimeStamp': 1234567,
        'bVehicleBodyHit': False,
        'bVehicleFLWheelHit': True,
        'bVehicleFRWheelHit': False,
        'bVehicleBLWheelHit': False,
        'bVehicleBRWheelHit': False,
        'bProgramEnd': False,
        'bFlameOut': False,
        'ReverseParkingLeftCount': 1,
        'ReverseParkingRightCount': 1,
        'bParkingTrace': False,
        'bIsInParkingArea': False,
        'PassThroughCheckpointCount': 2,
        'bIsPassingThroughCheckpoint': False,
        'bBridge1': False,
        'bBridge2': False,
        'bBridge3': False,
        'bBridge4': False,
        'bRampParking1': False,
        'bRampParking2': False,
        'RPM': 1,
        'bIsOnZebraCrossing': False,
        'bCanVehiclePassThrough': False,
        'bFLWheelHitDottedLine': False,
        'bFRWheelHitDottedLine': False,
        'bBLWheelHitDottedLine': False,
        'bBRWheelHitDottedLine': False,
        'bWheelHitSolidLine': False,
        'bIsInTurnAroundArea': False,
        'bWiperOn': False,
        'bIsHeadLightsOn': False,
        'WiperState': 2,
        'HeadlightsState': 1,
        'bFogLampOn': False,
        'bWidthIndicator': False,
        'bLimitDoorCheckPoint': False,
        'bHitPeopleOrCar': False,
        'bEmergencyOperation': False,
        'EmergencyTraining': 23,
        'bOnRightRoad': False,
        'bRunOverbedgeOfTheRoad': False,
        'bDrivingThroughRollingRoad': False,
        'bStopOnEmergencyVehicleLane': False,
        'bAboutToLeaveTheTunnel': False,
        'bDecelerateWithinTheSpecifiedRange': False,
        'bTurnAccordingToTheRules': False,
        'bGearOperationCorrect': False,
        'bStopInFiftyCm': False,
        'bStopInThirtyCm': False,
        'bAlternateUseLight': False,
        'bTurnAfterThreeSecond': False,
        'bActiveGuidancePracticeSuccessed': False,
        'bTurnAroundStep1': False,
        'bTurnAroundStep2': False,
        'bTurnAroundStep3': False,
        'bTurnAroundStep4': False
    }

    builder = flatbuffers.Builder(flatbuffers.Builder.MAX_BUFFER_SIZE)
    topic_string = builder.CreateString(str("server"))
    device_uuid = builder.CreateString(str("vehicle_client_test"))
    uuid = builder.CreateString(str(data['uuid']))
    player_id = builder.CreateString(str(data['player_id']))
    device_id = builder.CreateString(str(data['device_id']))

    Hoevo.VehicleInfo.VehicleInfoStart(builder)
    Hoevo.VehicleInfo.VehicleInfoAddUuid(builder, uuid)
    Hoevo.VehicleInfo.VehicleInfoAddPlayerId(builder, player_id)
    Hoevo.VehicleInfo.VehicleInfoAddDeviceId(builder, device_id)
    Hoevo.VehicleInfo.VehicleInfoAddEngineStart(builder, data['bEngineStart'])
    Hoevo.VehicleInfo.VehicleInfoAddHandBrake(builder, data['bHandBrake'])
    Hoevo.VehicleInfo.VehicleInfoAddClutchIntensity(builder, data['ClutchIntensity'])
    Hoevo.VehicleInfo.VehicleInfoAddBrakePedalIntensity(builder, data['BrakePedalIntensity'])
    Hoevo.VehicleInfo.VehicleInfoAddThrottleIntensity(builder, data['ThrottleIntensity'])
    Hoevo.VehicleInfo.VehicleInfoAddSafetyBelt(builder, data['bSafetyBelt'])
    Hoevo.VehicleInfo.VehicleInfoAddCurrentGear(builder, data['CurrentGear'])
    Hoevo.VehicleInfo.VehicleInfoAddAddGearByDegrees(builder, data['bAddGearByDegrees'])
    Hoevo.VehicleInfo.VehicleInfoAddCorneringLampState(builder, data['CorneringLampState'])
    Hoevo.VehicleInfo.VehicleInfoAddHorn(builder, data['bHorn'])
    Hoevo.VehicleInfo.VehicleInfoAddDoubleFlash(builder, data['bDoubleFlash'])
    Hoevo.VehicleInfo.VehicleInfoAddSteeringWheelAngle(builder, data['bDoubleFlash'])
    Hoevo.VehicleInfo.VehicleInfoAddSpeed(builder, 10)
    Hoevo.VehicleInfo.VehicleInfoAddTrainingProgram(builder, data['TrainingProgram'])
    Hoevo.VehicleInfo.VehicleInfoAddTimestamp(builder, data['TimeStamp'])
    Hoevo.VehicleInfo.VehicleInfoAddVehicleBodyHit(builder, data['bVehicleBodyHit'])
    Hoevo.VehicleInfo.VehicleInfoAddVehicleFlWheelHit(builder, data['bVehicleFLWheelHit'])
    Hoevo.VehicleInfo.VehicleInfoAddVehicleFrWheelHit(builder, data['bVehicleFRWheelHit'])
    Hoevo.VehicleInfo.VehicleInfoAddVehicleBlWheelHit(builder, data['bVehicleBLWheelHit'])
    Hoevo.VehicleInfo.VehicleInfoAddVehicleBrWheelHit(builder, data['bVehicleBRWheelHit'])
    Hoevo.VehicleInfo.VehicleInfoAddProgramEnd(builder, data['bProgramEnd'])
    Hoevo.VehicleInfo.VehicleInfoAddFlameout(builder, data['bFlameOut'])
    Hoevo.VehicleInfo.VehicleInfoAddReverseParkingLeftCount(builder, data['ReverseParkingLeftCount'])
    Hoevo.VehicleInfo.VehicleInfoAddReverseParkingRightCount(builder, data['ReverseParkingRightCount'])
    Hoevo.VehicleInfo.VehicleInfoAddParkingTrace(builder, data['bParkingTrace'])
    Hoevo.VehicleInfo.VehicleInfoAddInParkingArea(builder, data['bIsInParkingArea'])
    Hoevo.VehicleInfo.VehicleInfoAddPassThroughCheckpointCount(builder, data['PassThroughCheckpointCount'])
    Hoevo.VehicleInfo.VehicleInfoAddPassingThroughCheckpoint(builder, data['bIsPassingThroughCheckpoint'])
    Hoevo.VehicleInfo.VehicleInfoAddBridge1(builder, data['bBridge1'])
    Hoevo.VehicleInfo.VehicleInfoAddBridge2(builder, data['bBridge2'])
    Hoevo.VehicleInfo.VehicleInfoAddBridge3(builder, data['bBridge3'])
    Hoevo.VehicleInfo.VehicleInfoAddBridge4(builder, data['bBridge4'])
    Hoevo.VehicleInfo.VehicleInfoAddRampParking1(builder, data['bRampParking1'])
    Hoevo.VehicleInfo.VehicleInfoAddRampParking2(builder, data['bRampParking2'])
    Hoevo.VehicleInfo.VehicleInfoAddRpm(builder, data['RPM'])
    Hoevo.VehicleInfo.VehicleInfoAddOnZebraCrossing(builder, data['bIsOnZebraCrossing'])
    Hoevo.VehicleInfo.VehicleInfoAddCanVehiclePassThrough(builder, data['bCanVehiclePassThrough'])
    Hoevo.VehicleInfo.VehicleInfoAddFlWheelHitDottedLine(builder, data['bFLWheelHitDottedLine'])
    Hoevo.VehicleInfo.VehicleInfoAddFrWheelHitDottedLine(builder, data['bFRWheelHitDottedLine'])
    Hoevo.VehicleInfo.VehicleInfoAddBlWheelHitDottedLine(builder, data['bBLWheelHitDottedLine'])
    Hoevo.VehicleInfo.VehicleInfoAddBrWheelHitDottedLine(builder, data['bBRWheelHitDottedLine'])
    Hoevo.VehicleInfo.VehicleInfoAddWheelHitSolidLine(builder, data['bWheelHitSolidLine'])
    Hoevo.VehicleInfo.VehicleInfoAddInTurnAroundArea(builder, data['bIsInTurnAroundArea'])
    Hoevo.VehicleInfo.VehicleInfoAddWiperOn(builder, data['bWiperOn'])
    Hoevo.VehicleInfo.VehicleInfoAddIsHeadLightsOn(builder, data['bIsHeadLightsOn'])
    Hoevo.VehicleInfo.VehicleInfoAddWiperState(builder, data['WiperState'])
    Hoevo.VehicleInfo.VehicleInfoAddHeadlightsState(builder, data['HeadlightsState'])
    Hoevo.VehicleInfo.VehicleInfoAddFogLampOn(builder, data['bFogLampOn'])
    Hoevo.VehicleInfo.VehicleInfoAddWidthIndicator(builder, data['bWidthIndicator'])
    Hoevo.VehicleInfo.VehicleInfoAddLimitDoorCheckpoint(builder, data['bLimitDoorCheckPoint'])
    Hoevo.VehicleInfo.VehicleInfoAddHitPeopleOrCar(builder, data['bHitPeopleOrCar'])
    Hoevo.VehicleInfo.VehicleInfoAddEmergencyOperation(builder, data['bEmergencyOperation'])
    Hoevo.VehicleInfo.VehicleInfoAddEmergencyTraining(builder, data['EmergencyTraining'])
    Hoevo.VehicleInfo.VehicleInfoAddOnRightRoad(builder, data['bOnRightRoad'])
    Hoevo.VehicleInfo.VehicleInfoAddRunOverbedgeOfTheRoad(builder, data['bRunOverbedgeOfTheRoad'])
    Hoevo.VehicleInfo.VehicleInfoAddDrivingThroughRollingRoad(builder, data['bDrivingThroughRollingRoad'])
    Hoevo.VehicleInfo.VehicleInfoAddStopOnEmergencyVehicleLane(builder, data['bStopOnEmergencyVehicleLane'])
    Hoevo.VehicleInfo.VehicleInfoAddAboutToLeaveTheTunnel(builder, data['bAboutToLeaveTheTunnel'])
    Hoevo.VehicleInfo.VehicleInfoAddDecelerateWithinTheSpecifiedRange(builder, data['bDecelerateWithinTheSpecifiedRange'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAccordingToTheRules(builder, data['bTurnAccordingToTheRules'])
    Hoevo.VehicleInfo.VehicleInfoAddGearOperationCorrect(builder, data['bGearOperationCorrect'])
    Hoevo.VehicleInfo.VehicleInfoAddStopInFiftyCm(builder, data['bStopInFiftyCm'])
    Hoevo.VehicleInfo.VehicleInfoAddStopInThirtyCm(builder, data['bStopInThirtyCm'])
    Hoevo.VehicleInfo.VehicleInfoAddAlternateUseLight(builder, data['bAlternateUseLight'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAfterThreeSecond(builder, data['bTurnAfterThreeSecond'])
    Hoevo.VehicleInfo.VehicleInfoAddActiveGuidancePracticeSuccessed(builder, data['bActiveGuidancePracticeSuccessed'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAroundStep1(builder, data['bTurnAroundStep1'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAroundStep2(builder, data['bTurnAroundStep2'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAroundStep3(builder, data['bTurnAroundStep3'])
    Hoevo.VehicleInfo.VehicleInfoAddTurnAroundStep4(builder, data['bTurnAroundStep4'])
    vehicle_info_data = Hoevo.VehicleInfo.VehicleInfoEnd(builder)

    Hoevo.Payload.PayloadStart(builder)
    Hoevo.Payload.PayloadAddAnyType(builder, Hoevo.Any.Any().VehicleInfo)
    Hoevo.Payload.PayloadAddAny(builder, vehicle_info_data)
    payload = Hoevo.Payload.PayloadEnd(builder)

    builder.Finish(payload)
    payload = builder.Output()

    payload_bytes = bytearray(payload)
    Hoevo.PUBLISH.StartPayloadVector(builder, len(payload_bytes))
    for i in reversed(range(0, len(payload_bytes))):
        print(payload_bytes[i])
        builder.PrependByte(payload_bytes[i])
    payload = builder.EndVector()

    Hoevo.PUBLISH.PUBLISHStart(builder)
    Hoevo.PUBLISH.PUBLISHAddPayload(builder, payload)
    Hoevo.PUBLISH.PUBLISHAddPayloadType(builder, Hoevo.PayloadType.PayloadType().FBS)
    Hoevo.PUBLISH.PUBLISHAddTopic(builder, topic_string)
    Hoevo.PUBLISH.PUBLISHAddClientId(builder, device_uuid)
    Hoevo.PUBLISH.PUBLISHAddQos(builder, Hoevo.QoS.QoS().AtMostOnce)
    PUBLISH = Hoevo.PUBLISH.PUBLISHEnd(builder)

    Hoevo.Msg.MsgStart(builder)
    Hoevo.Msg.MsgAddFlag(builder, PUBLISH)
    Hoevo.Msg.MsgAddFlagType(builder, Hoevo.Flag.Flag().PUBLISH)
    msg = Hoevo.Msg.MsgEnd(builder)

    builder.Finish(msg)
    data = builder.Output()

    return data

def send_connect(ws):
    print("### send connect ###")
    connect = fbs_connect.SendConnect()
    connect.client_id = "vehicle_client_test"
    data = connect.send_fbs_connect()
    ws.send(data, 0x2)
    global websocket_connect
    websocket_connect = True
    time.sleep(2)
    send_login(ws)
    time.sleep(2)
    send_subscribe(ws)
    while True:
        send_VehicleInfo(ws)

def send_login(ws):
    print("### send login ###")
    login = fbs_login.SendLogin()
    login.client_id = "vehicle_client_test"
    login.ip = "127.0.0.1"
    data = login.send_fbs_login()
    ws.send(data, 0x2)

def send_VehicleInfo(ws):
    print("### send send_VehicleInfo ###")
    data = set_vehicle_info_to_data()
    ws.send(data, 0x2)

def send_subscribe(ws):
    print("### send subscribe ###")
    subscribe = fbs_subscribe.SendSubscribe()
    subscribe.topic = "server/#"
    subscribe.topic_1 = "server"
    subscribe.client_id = "vehicle_client_test"
    data = subscribe.send_subscribe()
    ws.send(data, 0x2)

def send_test_data(ws):
    print("### send subscribe ###")

def ws_connect():
    #websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://127.0.0.1:4001/ws/")
    ws.on_open = send_connect
    ws.run_forever()

if __name__ == '__main__':
    while True:
        ws_connect()


import os
import base64
import requests
import RPi.GPIO as GPIO
import time
import sys
from gpiozero import DistanceSensor

servoPIN1 = 2
GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN1, GPIO.OUT)
pwm1=GPIO.PWM(servoPIN1,50)
pwm1.start(90)

servoPIN2 = 3
GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN2, GPIO.OUT)
pwm2=GPIO.PWM(servoPIN2,50)
pwm2.start(90)

sensor1 = DistanceSensor(trigger=19, echo=26)
sensor2 = DistanceSensor(trigger=20, echo=21)
sensor3 = DistanceSensor(trigger=6, echo=13)

def SetAngle(angle):
    duty1 = angle/18 + 2
    duty2 = (180 - angle)/18 + 2
    GPIO.output(servoPIN1, True)
    pwm1.ChangeDutyCycle(duty1)
    GPIO.output(servoPIN2, True)
    pwm2.ChangeDutyCycle(duty2)
    time.sleep(1)
    GPIO.output(servoPIN1, False)
    pwm1.ChangeDutyCycle(0)
    GPIO.output(servoPIN2, False)
    pwm2.ChangeDutyCycle(0)

SetAngle(90)
SetAngle(0)
SetAngle(135)
SetAngle(0)
SetAngle(90)
pwm1.stop()
pwm2.stop()

while True:
    # Wait 2 seconds
    time.sleep(2)
                  # Get the distance in metres

    # But we want it in centimetres
    distance1 = sensor1.distance * 100
    distance2 = sensor2.distance * 100
    distance3 = sensor3.distance * 100

    # We would get a large decimal number so we will round it to 2 places

    # Print the information to the screen
    print("Distance1: {} cm".format(distance1))
    print("Distance2: {} cm".format(distance2))
    print("Distance3: {} cm".format(distance3))

GPIO.cleanup()