import json
import os
from biothings_explorer.smartapi_kg.metakg import MetaKG
from biothings_explorer.trapi.utils.errors.predicates_error import PredicatesLoadingError
from .utils import camel_to_snake

class MetaKnowledgeGraphHandler:
    def __init__(self, smart_API_id=None, team=None):
        self.smart_API_id = smart_API_id
        self.team = team

    def _load_meta_kg(self, smart_API_id=None, team=None):
        smartapi_specs = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'data', 'smartapi_specs.json'))

        predicates = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'data', 'predicates.json'))

        kg = MetaKG(smartapi_specs, predicates)

        try:
            if smart_API_id:
                kg.construct_MetaKG_sync(False, {'smart_API_id': smart_API_id})
            elif team:
                kg.construct_MetaKG_sync(False, {'team_name': team})
            else:
                kg.construct_MetaKG_sync(True, {})
            if len(kg.ops) == 0:
                raise PredicatesLoadingError({
                    'error': 'Unable to load predicates',
                    'more_info': 'Not Found - 0 operations'
                })
            return kg
        except PredicatesLoadingError as e:
            raise PredicatesLoadingError({
                'error': 'Unable to load predicates',
                'more_info': f"Failed to Load MetaKG: PredicatesLoadingError: {e.args[0]['more_info']}"
            })

    def _modify_category(self, category):
        if category.startswith('biolink:'):
            return 'biolink:' + category[8].upper() + category[9:]
        else:
            return 'biolink:' + category[0].upper() + category[1:]

    def _modify_predicate(self, predicate):
        if predicate.startswith('biolink:'):
            return 'biolink:' + camel_to_snake(predicate[8:])
        else:
            return 'biolink:' + camel_to_snake(predicate)

    def get_kg(self, smartapi_id=None, team=None):
        if not smartapi_id:
            smartapi_id = self.smart_API_id
        if not team:
            team = self.team
        kg = self._load_meta_kg(smartapi_id, team)
        knowledge_graph = {
            'nodes': {},
            'edges': []
        }
        predicates = {}
        file_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'ids.json'))
        f = open(file_path, )

        # returns JSON object as
        # a dictionary
        ids = json.load(f)
        for semantic_type in ids:
            knowledge_graph['nodes'][self._modify_category(semantic_type)] = {
                'id_prefixes': ids[semantic_type]['id_ranks']
            }
        f.close()
        for op in kg.ops:
            _input = self._modify_category(op['association']['input_type'])
            output = self._modify_category(op['association']['output_type'])
            pred = self._modify_predicate(op['association']['predicate'])
            if _input not in predicates:
                predicates[_input] = {}
            if output not in predicates[_input]:
                predicates[_input][output] = []
            if pred not in predicates[_input][output]:
                predicates[_input][output].append(pred)
        for _input in predicates:
            for output in predicates[_input]:
                for pr in predicates[_input][output]:
                    knowledge_graph['edges'].append({
                        'subject': _input,
                        'predicate': pr,
                        'object': output,
                        'relation': None
                    })
        return knowledge_graph


import sys
import cv2
import sys
import os
import itertools
import numpy

if __name__ == '__main__':

    #for fl in fls:
    fl=sys.argv[1]

    ptfln=open('%s_num.txt'%(fl))
    pts_num=int(ptfln.readline().strip())
    ptfln.close()

    pts_pos=[]
    pts_pf=open('%s_pos.txt'%(fl))

    for i in range(0,pts_num):
        pts_pos.append(pts_pf.readline().strip().split(' '))
    pts_pf.close()

    imagefilename = '%s.pgm'%(fl)
    img=cv2.imread(imagefilename, 1)
    for i in range(0,pts_num):
        p=(int(pts_pos[i][0]),int(pts_pos[i][1]))
        cv2.circle(img,p,2,(0,0,255))
    cv2.imshow("img",img)
    cv2.waitKey(0)


import aiofiles
from aiogram.dispatcher.storage import FSMContext
from aiogram.utils.exceptions import MessageTextIsEmpty, CantParseEntities, PhotoDimensions

from django_admin.bot.models import Page, InfoPage, InnerKeyboard
from filters import CommandBack, OtherWords

from keyboards.inline.buttons import choose_level

from states.state_machine import PositionState
from loader import dp, bot
from utils.debugger import debugger
from aiogram.types import Message

from keyboards.default import enrollee_menu as kb

import logging

from utils import google_sheets
from utils.db_api import db_commands
from utils.bot_commands.commands import commands

from handlers.groups.main_menu_group import group_menu

# * Формирование словаря кнопок первого уровня => кнопка : id
buttons = Page.objects.values("btn_title", "id")
buttons_id: dict = {btn['btn_title']: btn["id"] for btn in buttons}

# * Формирование словаря кнопок второго уровня => кнопка : id
inner_buttons = InnerKeyboard.objects.values("btn_title", "buttons_id")
inner_buttons_id: dict = {btn["btn_title"]: btn["buttons_id"] for btn in inner_buttons}

buttons_title_first = list(buttons_id)
keyboard = {"first": buttons_title_first}

buttons_title_second = list(inner_buttons_id)
keyboard["second"] = buttons_title_second

service_words = [*keyboard["first"], *keyboard["second"], *group_menu, "Назад", *(map(lambda c: f"/{c}", commands))]

# * Обработчик неслужебных слов
@dp.message_handler(OtherWords(service_words))
async def service_words_handler(message: Message):
    """
    Если пользователь ввел сообщение, которое не содержит закрепленные команды или названия кнопок, бот отвечает ему, \
    что не понимает сообщения

    :param message: переменная для манипуляции над сообщениями
    """
    await message.answer("Извините, но я не понимаю вашей команды")

# * Обработчик кнопки Назад
@dp.message_handler(CommandBack())
async def back_to_btn_handler(message: Message):
    """
    Обработчик нажатия кнопки "Назад"

    При нажатии переводит пользователя на уровень ниже

    :param message: переменная для манипуляции над сообщениями
    """
    await message.answer("Вы вернулись назад", reply_markup=await kb.generate_keyboard(
        one_time_keyboard=True
    ))

@dp.message_handler(text="Получить результаты")
async def get_results(message: Message):
    """
    Обработчик нажатия на кнопку "Получить результаты" в разделе "Тест на профориентацию"
    При нажатии обращается к API Google Sheet, для получения результата теста, если таковой имеется
    Если результата нет, бот возвращает пользователю сообщение о его отсутствии

    :param message: переменная для манипуляции над сообщениями
    """
    await message.answer("Ваш запрос обрабатывается. Подождите несколько секунд")

    query: dict = await db_commands.get_bak_directions()
    directions = dict(sorted(query.items(), key=lambda k: k[0]))

    result: str = await google_sheets.proftest_results.get_results(str(message.from_user.id), directions)
    try:
        await message.answer(result)

    except MessageTextIsEmpty:
        await message.answer("Вы еще не прошли профориентационный тест")

# * Обработчик клавиатуры первого уровня
@dp.message_handler(lambda message: message.text in keyboard["first"])
async def menu(message: Message, state: FSMContext):
    pressed_button: str = message.text
    btn_id: int = buttons_id[pressed_button]

    type_content: str = InfoPage.objects.get(id=btn_id).type_content

    try:
        comment: str = InfoPage.objects.get(
            id=btn_id
        ).info

        if type_content == "keyboard":
            await message.answer(
                comment, reply_markup=choose_level
            )
            await state.set_state(PositionState.set_pressed_btn)

            async with state.proxy() as data:
                inline_id: str = Page.objects.get(id=btn_id).inline_tag
                data["page"] = inline_id
            await PositionState.next()

        else:
            if pressed_button == "Тест на профориентацию":
                link = f"https://docs.google.com/forms/d/e/1FAIpQLSeNkbEzcvxl7JsUxuYu13ECBLlZZrxJNyBjC_krgnZbVrUcjQ/viewform?usp=pp_url&entry.834901947={message.from_user.id}"
                comment += f"\nСобственно, сам профориентационный тест"

            if Page.objects.get(btn_title=pressed_button).file.name not in [None, ""]:
                file_path: str = Page.objects.get(btn_title=pressed_button).file.path

                async with aiofiles.open(file_path, "rb") as photograph:
                    await bot.send_photo(
                        chat_id=message.chat.id, photo=photograph,
                        caption=comment,
                        reply_markup=await kb.generate_keyboard(btn_id)
                    )
            else:
                await message.answer(comment, reply_markup=await kb.generate_keyboard(btn_id))

    except MessageTextIsEmpty as error:
        await message.answer(f"Информации нет\n{debugger(error)}", parse_mode='')

    except PhotoDimensions as error:
        await message.answer(f"Ошибка вывода изображения: большое разрешение\n{debugger(error)}", parse_mode='')
        logging.error(error)

    except CantParseEntities as error:
        await message.answer(f"Ошибка! Неправильная разметка информации\n{debugger(error)}", parse_mode='')


import pytest

from rest_framework import status

from api.git_access.serializers import GitAccessSerializer
from constants.urls import API_V1
from db.models.clusters import Cluster
from db.models.git_access import GitAccess
from factories.factory_git_access import GitAccessFactory
from factories.factory_k8s_secrets import K8SSecretFactory
from tests.base.clients import AuthorizedClient
from tests.base.views import BaseViewTest

@pytest.mark.git_access_mark
class TestGitAccessListViewV1(BaseViewTest):
    serializer_class = GitAccessSerializer
    model_class = GitAccess
    factory_class = GitAccessFactory
    num_objects = 3
    HAS_AUTH = True
    ADMIN_USER = True

    def setUp(self):
        super().setUp()
        self.normal_client = AuthorizedClient()
        self.url = '/{}/catalogs/git_access/'.format(API_V1)
        self.objects = [self.factory_class() for _ in range(self.num_objects)]
        self.queryset = self.model_class.objects.filter()

    def test_get(self):
        resp = self.auth_client.get(self.url)
        assert resp.status_code == status.HTTP_200_OK

        assert resp.data['next'] is None
        assert resp.data['count'] == len(self.objects)

        data = resp.data['results']
        assert len(data) == self.queryset.count()
        for i in data:
            assert i in self.serializer_class(self.queryset, many=True).data

        # Non admin
        resp = self.normal_client.get(self.url)
        assert resp.status_code == status.HTTP_200_OK

        assert resp.data['next'] is None
        assert resp.data['count'] == len(self.objects)

        data = resp.data['results']
        assert len(data) == self.queryset.count()
        for i in data:
            assert i in self.serializer_class(self.queryset, many=True).data

    def test_pagination(self):
        limit = self.num_objects - 1
        resp = self.auth_client.get("{}?limit={}".format(self.url, limit))
        assert resp.status_code == status.HTTP_200_OK

        next_page = resp.data.get('next')
        assert next_page is not None
        assert resp.data['count'] == self.queryset.count()

        data = resp.data['results']
        assert len(data) == limit
        query_data = self.serializer_class(self.queryset, many=True).data
        for i in data:
            assert i in query_data

        resp = self.auth_client.get(next_page)
        assert resp.status_code == status.HTTP_200_OK

        assert resp.data['next'] is None

        data = resp.data['results']
        assert len(data) == 1
        for i in data:
            assert i in query_data

    def test_create(self):

        data = {}
        resp = self.auth_client.post(self.url, data)
        assert resp.status_code == status.HTTP_400_BAD_REQUEST

        secret = K8SSecretFactory()

        data = {
            'name': 'foo',
            'description': 'new description',
            'tags': ['foo', 'bar'],
            'host': 'https://foo.bar',
            'k8s_secret': secret.id,
        }
        resp = self.auth_client.post(self.url, data)
        assert resp.status_code == status.HTTP_201_CREATED
        assert self.model_class.objects.count() == self.num_objects + 1
        last_object = self.model_class.objects.last()
        assert last_object.owner.owner == Cluster.load()
        assert last_object.name == data['name']
        assert last_object.description == data['description']
        assert last_object.tags == data['tags']
        assert last_object.host == data['host']
        assert last_object.k8s_secret.id == data['k8s_secret']

        # Non admin
        data = {}
        resp = self.normal_client.post(self.url, data)
        assert resp.status_code == status.HTTP_403_FORBIDDEN

        data = {
            'name': 'foo',
            'description': 'new description',
            'tags': ['foo', 'bar'],
            'host': 'https://foo.bar',
            'k8s_secret': secret.id,
        }
        resp = self.normal_client.post(self.url, data)
        assert resp.status_code == status.HTTP_403_FORBIDDEN

@pytest.mark.git_access_mark
class TestGitAccessDetailViewV1(BaseViewTest):
    serializer_class = GitAccessSerializer
    model_class = GitAccess
    factory_class = GitAccessFactory
    HAS_AUTH = True
    ADMIN_USER = True

    def setUp(self):
        super().setUp()
        self.normal_client = AuthorizedClient()
        self.object = self.factory_class()
        self.url = '/{}/catalogs/git_access/{}/'.format(API_V1, self.object.name)
        self.queryset = self.model_class.objects.all()

    def test_get(self):
        resp = self.auth_client.get(self.url)
        assert resp.status_code == status.HTTP_200_OK
        assert resp.data == self.serializer_class(self.object).data

        # Non admin can get
        resp = self.normal_client.get(self.url)
        assert resp.status_code == status.HTTP_200_OK
        assert resp.data == self.serializer_class(self.object).data

    def test_patch(self):
        secret = K8SSecretFactory()

        data = {
            'name': 'foo',
            'description': 'new description',
            'tags': ['foo', 'bar'],
            'host': 'https://foo.bar',
            'k8s_secret': secret.id,
        }
        assert self.object.name != data['name']
        assert self.object.description != data['description']
        assert self.object.tags != data['tags']
        assert self.object.host != data['host']
        assert self.object.k8s_secret != data['k8s_secret']

        resp = self.auth_client.patch(self.url, data=data)
        assert resp.status_code == status.HTTP_200_OK
        new_object = self.model_class.objects.get(id=self.object.id)
        assert new_object.name == data['name']
        assert new_object.description == data['description']
        assert set(new_object.tags) == set(data['tags'])
        assert new_object.host == data['host']
        assert new_object.k8s_secret.id == data['k8s_secret']

        # Non admin
        resp = self.normal_client.patch(self.url, data=data)
        assert resp.status_code == status.HTTP_403_FORBIDDEN

    def test_delete(self):
        # Non admin
        resp = self.normal_client.delete(self.url)
        assert resp.status_code == status.HTTP_403_FORBIDDEN

        assert self.model_class.objects.count() == 1
        resp = self.auth_client.delete(self.url)
        assert resp.status_code == status.HTTP_204_NO_CONTENT
        assert self.model_class.objects.count() == 0


import shap
import pandas as pd
import plotly.express as px
import numpy as np
import plotly.subplots as sp
import plotly.graph_objs as go

px.defaults.color_continuous_scale = px.colors.sequential.Darkmint

def get_plot_global_feature_importance(model, columns ):
    importance_df = pd.DataFrame(dict(
    group = columns,
    value = model.feature_importances_))

    importance_df.sort_values('value',ascending=False, inplace = True)

    importance_df = importance_df[0:20]

    importance_df.sort_values('value', inplace = True)

    fig = px.bar(importance_df, y = 'group', x = 'value',
                 color = 'value')
    return fig

def get_plot_local_feature_importance(model, client_row):

    local_importance = model.predict(client_row, pred_contrib=True)[0][0:-1]

    # Sample data
    importance_df = pd.DataFrame(dict(
        group = client_row.columns,
        value = local_importance))

    importance_df.sort_values('value',ascending=False, inplace = True)

    importance_df = importance_df[0:20]

    importance_df.sort_values('value', inplace = True)

    fig = px.bar(importance_df, y = 'group', x = 'value',
                 color = 'value')
    fig. update_yaxes( side = 'right')
    fig.update_coloraxes(colorbar_x=-0.2)

    return fig

def barplot_client_majority(df, client_data):

    if(len(client_data) <= 0):
        return

    # Calculate the features of interest for the selected client
    client_amt_credit = client_data['AMT_CREDIT'].values[0]
    client_amt_annuity = client_data['AMT_ANNUITY'].values[0]
    client_amt_goods_price = client_data['AMT_GOODS_PRICE'].values[0]

    # Calculate the mean values for the majority age group
    majority_amt_credit = np.round(df['AMT_CREDIT'].mean(), decimals=2)
    majority_amt_annuity = np.round(df['AMT_ANNUITY'].mean(), decimals=2)
    majority_amt_goods_price = np.round(df['AMT_GOODS_PRICE'].mean(), decimals=2)

    # Create subplots for each feature comparison
    fig = sp.make_subplots(rows=2, cols=2, subplot_titles=(
        "AMT_CREDIT", "AMT_ANNUITY", "AMT_GOODS_PRICE"))

    fig.add_trace(go.Bar(x=['Client', 'Moyenne'], y=[client_amt_credit, majority_amt_credit],
                  name='AMT_CREDIT', text=[client_amt_credit, majority_amt_credit]), row=1, col=1)

    fig.add_trace(go.Bar(x=['Client', 'Moyenne'],
                         y=[client_amt_annuity, majority_amt_annuity], name='AMT_ANNUITY',
                         text=[client_amt_annuity, majority_amt_annuity]), row=1, col=2)

    fig.add_trace(go.Bar(x=['Client', 'Moyenne'],
                         y=[client_amt_goods_price, majority_amt_goods_price], name='AMT_GOODS_PRICE',
                         text=[client_amt_goods_price, majority_amt_goods_price]), row=2, col=1)

    # Update layout

    # id = client_data["SK_ID_CURR"].values[0]
    # fig.update_layout(
    #     title=f'Comparaison du client{id} à l\'ensembe des clients')

    return fig

def barplot_same_clients(df, client_data):

    if(len(client_data) <= 0):
        return

    # Calculate the features of interest for the selected client
    client_amt_credit = client_data['AMT_CREDIT'].values[0]
    client_amt_annuity = client_data['AMT_ANNUITY'].values[0]
    client_amt_goods_price = client_data['AMT_GOODS_PRICE'].values[0]

    client_EXT_SOURCE_3 = client_data['EXT_SOURCE_3'].values[0]
    client_EXT_SOURCE_2 = client_data['EXT_SOURCE_2'].values[0]
    client_PAYMENT_RATE = client_data['PAYMENT_RATE'].values[0]

    # Calculate the mean values for the majority age group

    same_clients = df[
        (df['AMT_CREDIT'] <= client_amt_credit*1.10)  & (df['AMT_CREDIT'] >= client_amt_credit*0.90)
        & (df['AMT_ANNUITY'] <= client_amt_annuity*1.10) & (df['AMT_ANNUITY'] >= client_amt_annuity*0.90)
        & (df['AMT_GOODS_PRICE'] <= client_amt_goods_price*1.10)  & (df['AMT_GOODS_PRICE'] >= client_amt_goods_price*0.90)

    ]
    print(same_clients.shape)

    mean_same_client_amt_credit = np.round(same_clients['EXT_SOURCE_3'].mean(), decimals=2)
    mean_same_client_amt_annuity = np.round(same_clients['EXT_SOURCE_2'].mean(), decimals=2)
    mean_same_client_goods_price = np.round(same_clients['PAYMENT_RATE'].mean(), decimals=2)

    # Create subplots for each feature comparison
    fig = sp.make_subplots(rows=2, cols=2, subplot_titles=(
        "EXT_SOURCE_3", "EXT_SOURCE_2", "PAYMENT_RATE"))

    fig.add_trace(go.Bar(x=['Client', 'Clients similaires'], y=[client_EXT_SOURCE_3, mean_same_client_amt_credit],
                  name='EXT_SOURCE_3', text=[client_EXT_SOURCE_3, mean_same_client_amt_credit]), row=1, col=1)

    fig.add_trace(go.Bar(x=['Client', 'Clients similaires'],
                         y=[client_EXT_SOURCE_2, mean_same_client_amt_annuity], name='EXT_SOURCE_2',
                         text=[client_EXT_SOURCE_2, mean_same_client_amt_annuity]), row=1, col=2)

    fig.add_trace(go.Bar(x=['Client', 'Clients similaires'],
                         y=[client_PAYMENT_RATE, mean_same_client_goods_price], name='PAYMENT_RATE',
                         text=[client_PAYMENT_RATE, mean_same_client_goods_price]), row=2, col=1)

    # # Update layout
    # id = client_data["SK_ID_CURR"].values[0]
    # fig.update_layout(
    #     title=f'Comparaison du client{id} à l\'ensembe des clients')

    return fig


import copy

import cv2
import numpy as np
import onnxruntime

class YolopONNX(object):
    def __init__(
        self,
        model_path='yolop-640-640.onnx',
        input_shape=(640, 640),
        score_th=0.3,
        nms_th=0.45,
        providers=['CPUExecutionProvider'],
    ):
        # 入力サイズ
        self.input_shape = input_shape

        # 閾値
        self.class_score_th = score_th
        self.nms_th = nms_th

        # モデル読み込み
        self.onnx_session = onnxruntime.InferenceSession(
            model_path,
            providers=providers,
        )

    def inference(self, image):
        # 前処理
        rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        resize_rgb_image, r, dw, dh, new_unpad_w, new_unpad_h = self._resize_unscale(
            rgb_image,
            self.input_shape,
        )

        input_image = resize_rgb_image.copy().astype(np.float32)
        mean = [0.485, 0.456, 0.406]
        std = [0.229, 0.224, 0.225]
        input_image = (input_image / 255 - mean) / std
        input_image = input_image.transpose(2, 0, 1)
        input_image = np.expand_dims(input_image, axis=0)
        input_image = input_image.astype('float32')

        # 推論
        det_out, drive_area_seg, lane_line_seg = self.onnx_session.run(
            ['det_out', 'drive_area_seg', 'lane_line_seg'],
            input_feed={"images": input_image},
        )

        # NMS
        bboxes = self._nms(
            det_out,
            conf_thres=self.class_score_th,
            iou_thres=self.nms_th,
            agnostic=False,
        )[0]

        # バウンディングボックスの座標を元画像のスケールに変換
        bboxes[:, 0] -= dw
        bboxes[:, 1] -= dh
        bboxes[:, 2] -= dw
        bboxes[:, 3] -= dh
        bboxes[:, :4] /= r

        # 各セグメンテーション領域を選択する
        drive_area_seg = drive_area_seg[:, :, dh:dh + new_unpad_h,
                                        dw:dw + new_unpad_w]
        lane_line_seg = lane_line_seg[:, :, dh:dh + new_unpad_h,
                                      dw:dw + new_unpad_w]

        drive_area_seg_mask = np.argmax(drive_area_seg, axis=1)[0]
        lane_line_seg_mask = np.argmax(lane_line_seg, axis=1)[0]

        return bboxes, drive_area_seg_mask, lane_line_seg_mask

    def draw(
        self,
        image,
        bboxes,
        drive_area_seg_mask,
        lane_line_seg_mask,
    ):
        image_height, image_width, _ = image.shape
        debug_image = copy.deepcopy(image)

        # 道路セグメンテーション
        bg_image = np.zeros(image.shape, dtype=np.uint8)
        bg_image[:] = [0, 255, 0]

        mask = np.stack((drive_area_seg_mask, ) * 3, axis=-1).astype('uint8')
        mask = cv2.resize(
            mask,
            dsize=(image_width, image_height),
            interpolation=cv2.INTER_LINEAR,
        )
        mask = np.where(mask > 0.5, 0, 1)

        mask_image = np.where(mask, debug_image, bg_image)
        debug_image = cv2.addWeighted(debug_image, 0.5, mask_image, 0.5, 1.0)

        # レーンセグメンテーション
        bg_image = np.zeros(image.shape, dtype=np.uint8)
        bg_image[:] = [255, 0, 0]

        mask = np.stack((lane_line_seg_mask, ) * 3, axis=-1).astype('uint8')
        mask = cv2.resize(
            mask,
            dsize=(image_width, image_height),
            interpolation=cv2.INTER_LINEAR,
        )
        mask = np.where(mask > 0.5, 0, 1)

        mask_image = np.where(mask, debug_image, bg_image)
        debug_image = cv2.addWeighted(debug_image, 0.5, mask_image, 0.5, 1.0)

        # 車バウンディングボックス
        for bbox in bboxes:
            x1, y1 = int(bbox[0]), int(bbox[1])
            x2, y2 = int(bbox[2]), int(bbox[3])
            # score = bbox[4]
            # class_id = int(bbox[5])
            cv2.rectangle(debug_image, (x1, y1), (x2, y2), (0, 0, 255), 2, 2)

        return debug_image

    def _xywh2xyxy(self, x):
        y = np.zeros_like(x)
        y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left x
        y[:, 1] = x[:, 1] - x[:, 3] / 2  # top left y
        y[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right x
        y[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right y
        return y

    def _box_iou(self, box1, box2):
        def box_area(box):
            # (x2 - x1) * (y2 - y1)
            return (box[2] - box[0]) * (box[3] - box[1])

        area1 = box_area(box1.T)
        area2 = box_area(box2.T)

        # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)
        inter = (np.min(box1[:, None, 2:], box2[:, 2:]) -
                 np.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2)
        # iou = inter / (area1 + area2 - inter)
        return inter / (area1[:, None] + area2 - inter)

    def _nms(
        self,
        prediction,
        conf_thres=0.25,
        iou_thres=0.45,
        agnostic=False,
    ):
        xc = prediction[..., 4] > conf_thres  # candidates

        # Settings
        max_wh = 4096  # (pixels) minimum and maximum box width and height
        max_det = 300  # maximum number of detections per image
        redundant = True  # require redundant detections
        merge = False  # use merge-NMS

        output = [np.zeros((0, 6))] * prediction.shape[0]
        for xi, x in enumerate(prediction):  # image index, image inference
            x = x[xc[xi]]  # confidence

            # If none remain process next image
            if not x.shape[0]:
                continue

            # Compute conf
            x[:, 5:] *= x[:, 4:5]  # conf = obj_conf * cls_conf

            # Box (center x, center y, width, height) to (x1, y1, x2, y2)
            box = self._xywh2xyxy(x[:, :4])

            # Detections matrix nx6 (xyxy, conf, cls)
            conf = copy.deepcopy(x[:, 5:])
            j = np.zeros((x[:, 5:].shape[0], 1))
            x = np.concatenate((box, conf, j), 1)

            # Batched NMS
            c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
            # boxes (offset by class), scores
            boxes, scores = x[:, :4] + c, x[:, 4]
            i = cv2.dnn.NMSBoxes(
                bboxes=boxes.tolist(),
                scores=scores.tolist(),
                score_threshold=0.3,
                nms_threshold=0.45,
                top_k=5000,
            )
            if len(i) > 0:
                i = i.flatten()
                # limit detections
                if i.shape[0] > max_det:
                    i = i[:max_det]
                # Merge NMS (boxes merged using weighted mean)
                if merge and (1 < n < 3E3):
                    # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
                    # iou matrix
                    iou = self._box_iou(boxes[i], boxes) > iou_thres
                    # box weights
                    weights = iou * scores[None]
                    # merged boxes
                    x[i, :4] = np.dot(weights, x[:, :4]).float() / weights.sum(
                        1, keepdim=True)
                    if redundant:
                        # require redundancy
                        i = i[iou.sum(1) > 1]

                output[xi] = x[i]

        return output

    def _resize_unscale(self, img, new_shape=(640, 640), color=114):
        shape = img.shape[:2]  # current shape [height, width]
        if isinstance(new_shape, int):
            new_shape = (new_shape, new_shape)

        resize_rgb_image = np.zeros((new_shape[0], new_shape[1], 3))
        resize_rgb_image.fill(color)
        # Scale ratio (new / old) new_shape(h,w)
        r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])

        # Compute padding
        new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))  # w,h
        new_unpad_w = new_unpad[0]
        new_unpad_h = new_unpad[1]
        pad_w, pad_h = new_shape[1] - new_unpad_w, new_shape[
            0] - new_unpad_h  # wh padding

        dw = pad_w // 2  # divide padding into 2 sides
        dh = pad_h // 2

        if shape[::-1] != new_unpad:  # resize
            img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_AREA)

        resize_rgb_image[dh:dh + new_unpad_h, dw:dw + new_unpad_w, :] = img

        return resize_rgb_image, r, dw, dh, new_unpad_w, new_unpad_h  # (dw,dh)

if __name__ == "__main__":
    yolop = YolopONNX(
        model_path='weights/yolop-640-640.onnx',
        input_shape=(640, 640),
        providers=['CUDAExecutionProvider', 'CPUExecutionProvider'],
    )

    video_capture = cv2.VideoCapture("video/sample.mp4")

    while True:
        ret, frame = video_capture.read()
        if not ret:
            break

        bboxes, da_seg_mask, ll_seg_mask = yolop.inference(frame)
        result_image = yolop.draw(
            frame,
            bboxes,
            da_seg_mask,
            ll_seg_mask,
        )

        result_image = cv2.resize(result_image, dsize=None, fx=0.5, fy=0.5)

        cv2.imshow("YOLOP", result_image)
        key = cv2.waitKey(1)
        if key == 27:  # ESC
            break

    video_capture.release()
    cv2.destroyAllWindows()


import django
from django.conf import settings
from tracker.models import parse_query, Tracker
from tracker.models import Statistic, make_daily_report
from django.test import TestCase

import datetime

class UnitTestCase(TestCase):

    def test_query_string(self):

        query = "label1"
        self.assertEqual(parse_query(query), [{'lbl': 'label1'}])
        query = "label1|label2"
        self.assertEqual(parse_query(query), [{'lbl': 'label1'},
            {'lbl': 'label2'}])

        query = "label1:cat|label2"
        self.assertEqual(parse_query(query), [{'lbl': 'label1', 'cat': 'cat'},
            {'lbl': 'label2'}])

        query = "label1:cat:ele1|label2"
        self.assertEqual(parse_query(query),
            [{'lbl': 'label1', 'cat': 'cat', 'domid': 'ele1'},
            {'lbl': 'label2'}])

    def test_traker(self):

        tracker = Tracker()

        tracker.incr_labels('label1')
        self.assertEqual(tracker.labels, {'label1': {'lbl': 'label1'}})
        tracker.incr_labels('label1')
        self.assertEqual(tracker.flush_label('label1'), 2)
        self.assertEqual(tracker.flush_label('label1'), 0)
        tracker.save()

        tracker = Tracker()
        self.assertEqual(tracker.labels, {'label1': {'lbl': 'label1'}})
        tracker.reset_cache()

    def test_report(self):

        tracker = Tracker()
        tracker.incr_labels('label1:cat1:dom1')
        tracker.incr_labels('label1:cat1:dom1')

        self.assertEqual(Statistic.objects.count(), 0)

        make_daily_report()

        self.assertEqual(tracker.flush_label('label1'), 0)

        self.assertEqual(Statistic.objects.count(), 1)

        stat = Statistic.objects.all()[0]
        self.assertEqual(stat.counter, 2)
        self.assertEqual(stat.category, 'cat1')
        self.assertEqual(stat.dom_id, 'dom1')

        tracker.incr_labels('label1:cat1:dom1')
        tracker.incr_labels('label1:cat1:dom1')

        stat = Statistic.objects.all()[0]
        self.assertEqual(stat.counter, 2)

        make_daily_report()

        stat = Statistic.objects.all()[0]
        self.assertEqual(stat.counter, 4)

        tracker.reset_cache()


import nltk

class Analyzer():
    """Implements sentiment analysis."""

    def __init__(self, positives, negatives):
        """Initialize Analyzer."""
        # loads the text files with words into lists

        # initialize lists
        self.positives = []
        self.negatives = []

        # open file with positive words
        with open(positives) as lines:
            for line in lines:
                # if not starting with ; or space
                if not line.startswith((";", " ")):
                    self.positives.extend(line.rsplit("\n"))

        with open(negatives) as lines:
            for line in lines:
                if not line.startswith((";", " ")):
                    self.negatives.extend(line.rsplit("\n"))

    def analyze(self, text):
        """Analyze text for sentiment, returning its score."""

        # breaks the tweet sent into words/tokens
        tokenizer = nltk.tokenize.TweetTokenizer()
        tokens = tokenizer.tokenize(text)

        score = 0

        # for each word in the tweet
        for token in tokens:

            # calculates the score
            # convert all cases to lower case using lower()
            if token.lower() in self.positives:
                score = score + 1
            elif token.lower() in self.negatives:
                score = score - 1

        # returns the score
        return score


import torch
from torchtext.legacy import data
import torch.optim as optim
from torch import nn
from transformers import BertForMaskedLM
from transformers import BertJapaneseTokenizer
import numpy as np

tokenizer = BertJapaneseTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-whole-word-masking")
MAX_LENGTH = 512

def tokenizer_512(input_text):
    """torchtextのtokenizerとして扱えるように、512単語のpytorchでのencodeを定義。ここで[0]を指定し忘れないように"""
    return tokenizer.encode(input_text, max_length=MAX_LENGTH, truncation=True, return_tensors='pt')[0]

def mask_text(text_ids):
    input_ids = []
    for inp in text_ids.numpy():
        actual_tokens = list(set(range(512)) - set(np.where((inp==1) | (inp==2) | (inp==3)|(inp==0))[0].tolist()))
        num_of_token_to_mask = int(len(actual_tokens)*0.15)
        token_to_mask = np.random.choice(np.array(actual_tokens), size=num_of_token_to_mask, replace=False).tolist()
        inp[token_to_mask] = 4
        input_ids.append(inp)
    input_ids = torch.tensor(input_ids)
    return input_ids

def train_model(net, dataloaders_dict, criterion, optimizer, num_epochs):
    # GPUが使えるかを確認
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print("使用デバイス：", device)
    print('-----start-------')

    # ネットワークをGPUへ
    net.to(device)
    # ネットワークがある程度固定であれば、高速化させる
    torch.backends.cudnn.benchmark = True

    # ミニバッチのサイズ
    batch_size = dataloaders_dict["train"].batch_size

     # epochのループ
    for epoch in range(num_epochs):
        # epochごとの訓練と検証のループ
        for phase in ['train', 'val']:
            if phase == 'train':
                net.train()  # モデルを訓練モードに
            else:
                net.eval()   # モデルを検証モードに

            epoch_loss = 0.0  # epochの損失和
            iteration = 1
            # データローダーからミニバッチを取り出すループ
            for batch in (dataloaders_dict[phase]):
                labels = batch.Text[0]
                inputs = mask_text(batch.Text[0]).to(device)
                attn_mask = torch.where(inputs==0, 0, 1).to(device) # attention maskの作成

            # optimizerを初期化
                optimizer.zero_grad()

                # 順伝搬（forward）計算
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = net(input_ids=inputs, attention_mask=attn_mask).logits
                    outputs = outputs.reshape(-1,32000)

                    labels = torch.flatten(labels).to(device)

                    loss = criterion(outputs, labels)
                    # 訓練時はバックプロパゲーション
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                        if (iteration % 10 == 0):  # 10iterに1度、lossを表示
                            print('イテレーション {} || Loss: {:.4f} || 10iter.'.format(
                                iteration, loss.item()))

                    iteration += 1
                    # 損失と正解数の合計を更新
                    epoch_loss += loss.item() * batch_size
            # epochごとのlossと正解率
            epoch_loss = epoch_loss / len(dataloaders_dict[phase].dataset)
            print('Epoch {}/{} | {:^5} |  Loss: {:.4f}'.format(epoch+1, num_epochs, phase, epoch_loss))
    return net

def main():
    TEXT = data.Field(sequential=True, tokenize=tokenizer_512, use_vocab=False, lower=False,
                                include_lengths=True, batch_first=True, fix_length=MAX_LENGTH, pad_token=0)

    dataset_train, dataset_valid, dataset_test = data.TabularDataset.splits(
        path="btsj4finetune", train="train.tsv", validation="valid.tsv",test="test.tsv", format="tsv", fields=[
            ("Text", TEXT)])

    # DataLoaderを作成します（torchtextの文脈では単純にiteraterと呼ばれています）
    batch_size = 8 # BERTでは16、32あたりを使用する

    dl_train = data.Iterator(
        dataset_train, batch_size=batch_size, train=True)

    dl_valid = data.Iterator(
        dataset_valid, batch_size=batch_size, train=False, sort=False)

    dl_test = data.Iterator(
        dataset_test, batch_size=batch_size, train=False, sort=False)

    # 辞書オブジェクトにまとめる
    dataloaders_dict = {"train": dl_train, "val": dl_valid}

    net = BertForMaskedLM.from_pretrained("cl-tohoku/bert-base-japanese-whole-word-masking")
    # 訓練モードに設定
    net.train()

    # 1. まず全部を、勾配計算Falseにしてしまう
    for param in net.parameters():
        param.requires_grad = False
    # 2. BertOnlyMLMHeadだけ勾配計算Trueに変更
    for param in net.cls.parameters():
        param.requires_grad = True
    # 3. BertLayerモジュールの最後を勾配計算ありに変更
    for param in net.bert.encoder.layer[-1].parameters():
        param.requires_grad = True

    # 全部を、勾配計算Trueにしてしまう
    # for param in net.parameters():
    #     param.requires_grad = True

    optimizer = optim.Adam([
        {'params': net.bert.encoder.layer[-1].parameters(), 'lr': 5e-5},
        {"params": net.cls.parameters(), "lr": 5e-5},
    ])

    criterion = nn.CrossEntropyLoss()

    num_epochs = 5
    net_trained = train_model(net, dataloaders_dict, criterion, optimizer, num_epochs)

    # モデルの保存
    torch.save(net_trained.state_dict(), "model/model_trained.pt")

if __name__ == "__main__":
    main()


import sys
import pathlib
import contextlib
import tempfile
import pytest
import sxs

from .conftest import shortest_h_com_file, shortest_horizons, shortest_metadata

if sys.platform.startswith("win"):
    forked = pytest.mark.skip(reason="Windows has no way of forking")
else:
    forked = pytest.mark.forked

@pytest.mark.parametrize("persistent", (True, False))
def test_sxs_directory_bad_directory_name(persistent):
    with pytest.raises(ValueError):
        sxs.utilities.sxs_directory("cacheconfig", persistent=persistent)

@pytest.mark.parametrize(
    ("directory_type", "persistent"),
    (
        pytest.param("config", True, id="config persistent"),
        pytest.param("cache", True, id="cache persistent"),
        pytest.param("config", False, id="config temporary"),
        pytest.param("cache", False, id="cache temporary"),
    ),
)
@forked
def test_sxs_directory_cache_env(directory_type, persistent, tmp_path, monkeypatch):
    import pathlib
    import os

    sxs.utilities.sxs_directory.cache_clear()
    with monkeypatch.context() as mp:
        mp.setattr(pathlib.Path, "home", lambda: tmp_path)
        mp.setenv(f"SXS{directory_type.upper()}DIR", str(tmp_path))
        sxs_dir = sxs.utilities.sxs_directory(directory_type, persistent=persistent)
    assert isinstance(sxs_dir, pathlib.Path)
    if persistent:
        assert str(tmp_path) == str(sxs_dir)
    else:
        assert str(tmp_path) != str(sxs_dir)
    assert sxs_dir.exists()
    d = sxs_dir / "sub"
    d.mkdir()
    assert d.exists()
    p = d / "hello.txt"
    p.write_text("hi there")
    assert p.exists()
    assert p.read_text() == "hi there"

@pytest.mark.parametrize(
    ("directory_type", "platform"),
    (
        pytest.param("config", "linux", id="config linux"),
        pytest.param("cache", "linux", id="cache linux"),
        pytest.param("config", "freebsd", id="config freebsd"),
        pytest.param("cache", "freebsd", id="cache freebsd"),
    ),
)
def test_sxs_directory_linux(directory_type, platform, tmp_path, monkeypatch):
    import pathlib
    import sys

    d1 = tmp_path / "sub1"
    d1.mkdir()
    assert d1.exists()
    d2 = tmp_path / "sub2"
    d2.mkdir()
    assert d2.exists()

    with monkeypatch.context() as mp:
        mp.setattr(sys, "platform", platform)
        mp.setattr(pathlib.Path, "home", lambda: d1)

        mp.setenv(f'XDG_{directory_type.upper()}_HOME', str(d2))
        sxs.utilities.sxs_directory.cache_clear()
        sxs_dir = sxs.utilities.sxs_directory(directory_type, persistent=True)
        assert str(sxs_dir) == str(d2 / "sxs")

        mp.delenv(f'XDG_{directory_type.upper()}_HOME')
        sxs.utilities.sxs_directory.cache_clear()
        sxs_dir = sxs.utilities.sxs_directory(directory_type, persistent=True)
        assert str(sxs_dir) == str(d1 / f".{directory_type}" / "sxs")

@pytest.mark.parametrize(
    ("directory_type",), (pytest.param(dt, id=dt) for dt in ["config", "cache"]),
)
@forked
def test_sxs_directory_unwritable(directory_type, tmp_path, monkeypatch):
    import time
    import os
    import stat
    from pathlib import Path

    d = tmp_path / "unwritable"
    d.mkdir(mode=0o000)
    assert d.exists()
    assert d.is_dir()
    assert stat.filemode(d.stat().st_mode) == "d---------"
    assert not os.access(str(d), os.W_OK)

    with monkeypatch.context() as mp:
        mp.setattr(Path, "home", lambda: d)
        mp.setenv(f"SXS{directory_type.upper()}DIR", str(d))
        for dir_type in ["config", "cache"]:
            mp.delenv(f'XDG_{dir_type.upper()}_HOME', raising=False)
        sxs.utilities.sxs_directory.cache_clear()
        with pytest.warns(UserWarning):
            sxs_dir = sxs.utilities.sxs_directory(directory_type, persistent=True)
        assert ".sxs" not in str(sxs_dir), (str(sxs_dir), str(d))
        sxs_config_dir = sxs.utilities.sxs_directory("config", persistent=True)
        assert str(sxs_config_dir) in str(sxs_dir)

    d.chmod(0o777)
    time.sleep(0.1)

def test_read_write_config(tmp_path, monkeypatch):
    import pathlib

    sxs.utilities.sxs_directory.cache_clear()
    original_config = sxs.utilities.read_config()

    sxs.utilities.sxs_directory.cache_clear()
    with monkeypatch.context() as mp:
        mp.setattr(pathlib.Path, "home", lambda: tmp_path)
        mp.setenv(f"SXSCONFIGDIR", str(tmp_path))
        assert not sxs.utilities.read_config()
        sxs.utilities.write_config(NONSENSEGARBAGE=123)
        read = sxs.utilities.read_config()
        assert len(read) == 1
        assert read["NONSENSEGARBAGE"] == 123
        assert sxs.utilities.read_config("NONSENSEGARBAGE", 345) == 123
        assert sxs.utilities.read_config("NONSENSEGARBAGEJUNK", 345) == 345
        sxs.utilities.write_config(NONSENSEGARBAGEJUNK=345)
        assert sxs.utilities.read_config("NONSENSEGARBAGE", 345) == 123
        assert sxs.utilities.read_config("NONSENSEGARBAGEJUNK", 567) == 345

    sxs.utilities.sxs_directory.cache_clear()
    final_config = sxs.utilities.read_config()
    assert sorted(set(original_config)) == sorted(set(final_config))
    for k in original_config:
        assert original_config[k] == final_config[k]

def test_sxs_directory_cache_from_config(tmp_path, monkeypatch):
    import pathlib
    import os

    sxs.utilities.sxs_directory.cache_clear()
    with monkeypatch.context() as mp:
        mp.setattr(pathlib.Path, "home", lambda: tmp_path)
        sxs.utilities.write_config(cache_directory=str(tmp_path / "newcache"))
        sxs_dir = sxs.utilities.sxs_directory("cache", persistent=True)
    assert isinstance(sxs_dir, pathlib.Path)
    assert str(sxs_dir) == str(tmp_path / "newcache")

def test_select_by_path_component():
    from sxs.utilities import select_by_path_component

    # Examples given in the docstring
    possible_matches = [
        "abc/lm/xyz",
        "abc/ln/xyz",
        "abd/lm/xyz",
        "abd/ln/xyz",
    ]
    assert select_by_path_component("ab/ln/xyz", possible_matches) == {"abd/ln/xyz"}
    assert select_by_path_component("ab./ln/xyz", possible_matches) == {"abc/ln/xyz", "abd/ln/xyz"}
    assert select_by_path_component("a./ln/xyz", possible_matches) == {"abd/ln/xyz"}
    assert select_by_path_component("ab./l./x", possible_matches) == {"abc/lm/xyz", "abc/ln/xyz", "abd/lm/xyz", "abd/ln/xyz"}
    assert select_by_path_component("ab./l/x", possible_matches) == {"abc/ln/xyz", "abd/ln/xyz"}

    possible_matches += ["abe/lp/xyz"]
    assert select_by_path_component("ab/ln/xyz", possible_matches) == set()
    assert select_by_path_component("ab./ln/xyz", possible_matches) == {"abc/ln/xyz", "abd/ln/xyz"}
    assert select_by_path_component("a./ln/xyz", possible_matches) == set()
    assert select_by_path_component("ab./l./x", possible_matches) == set(possible_matches)
    assert select_by_path_component("ab./l/x", possible_matches) == {"abc/ln/xyz", "abd/ln/xyz", "abe/lp/xyz"}

    assert select_by_path_component("ab./l", possible_matches) == {"abc/ln/xyz", "abd/ln/xyz", "abe/lp/xyz"}

    assert select_by_path_component("abe/lp/xyz", ["abe/lp/xyz"]) == {"abe/lp/xyz"}

    # Fake SXS catalog
    fake_sxs = [
        f"SXS:BBH:{sxs_id:04}v{version}/Lev{lev}/{type}_{extrapolation}.h5"
        for sxs_id in range(1, 2023)
        for version in [1, 3]
        for lev in [2, 3, 4]
        for type in ["h", "psi4"]
        for extrapolation in ["extrapolated_n2", "extrapolated_n3", "extrapolated_n4"]
    ]

    assert select_by_path_component("SXS:BBH:012(3|4)/Lev/h.*n(2|3)", fake_sxs) == set(
        f"SXS:BBH:{sxs_id:04}v{version}/Lev{lev}/{type}_{extrapolation}.h5"
        for sxs_id in [123, 124]
        for version in [3]
        for lev in [4]
        for type in ["h"]
        for extrapolation in ["extrapolated_n2", "extrapolated_n3"]
    )

    assert select_by_path_component("SXS:B/Lev4/psi4", fake_sxs) == set(
        f"SXS:BBH:{sxs_id:04}v{version}/Lev{lev}/{type}_{extrapolation}.h5"
        for sxs_id in [2022]
        for version in [3]
        for lev in [4]
        for type in ["psi4"]
        for extrapolation in ["extrapolated_n4"]
    )

    assert select_by_path_component("SXS:BHWD/Lev4/psi4", fake_sxs) == set()

    assert select_by_path_component("SXS:BBH:1001v3/Lev3/h_extrapolated_n3.h5", fake_sxs) == set(
        f"SXS:BBH:{sxs_id:04}v{version}/Lev{lev}/{type}_{extrapolation}.h5"
        for sxs_id in [1001]
        for version in [3]
        for lev in [3]
        for type in ["h"]
        for extrapolation in ["extrapolated_n3"]
    )

    assert select_by_path_component("SXS:BBH:1001v3/Lev3/h", fake_sxs) == set(
        f"SXS:BBH:{sxs_id:04}v{version}/Lev{lev}/{type}_{extrapolation}.h5"
        for sxs_id in [1001]
        for version in [3]
        for lev in [3]
        for type in ["h"]
        for extrapolation in ["extrapolated_n2", "extrapolated_n3", "extrapolated_n4"]
    )

@pytest.mark.parametrize("truncation_tol", (True, None, 1e-9))
def test_lvcnr_format(truncation_tol):
    import shutil
    sxs_id = sxs.sxs_id(shortest_h_com_file)
    sxs_lev = sxs.lev_number(shortest_h_com_file)
    shortest_lvcnr = f"{sxs_id.replace(':', '_')}_Res{sxs_lev}.h5"
    # shortest_system = pathlib.PosixPath(shortest_h_com_file).parent
    # shortest_system_path = sxs.sxs_directory("cache") / sxs.utilities.sxs_path_to_system_path(shortest_h_com_file)
    with contextlib.redirect_stdout(None), contextlib.redirect_stderr(None):
        # Load these files, just to ensure they exist
        sxs.load(shortest_h_com_file, download=True, cache=True, progress=False, extrapolation_order=2)
        sxs.load(shortest_horizons, download=True, cache=True, progress=False)
        sxs.load(shortest_metadata, download=True, cache=True, progress=False)
        # Get the truepath values
        truepath_h = sxs.utilities.cached_path(shortest_h_com_file)
        truepath_horizons = sxs.utilities.cached_path(shortest_horizons)
        truepath_metadata = sxs.utilities.cached_path(shortest_metadata)
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = pathlib.Path(temp_dir)
            temp_sxs_path = temp_path / f"Lev{sxs_lev}"
            temp_sxs_path.mkdir(parents=True)
            shutil.copy(str(truepath_h), str(temp_sxs_path))
            shutil.copy(str(truepath_horizons), str(temp_sxs_path))
            shutil.copy(str(truepath_metadata), str(temp_sxs_path))
            lvc_converter = sxs.utilities.lvcnr.SimulationConverter(quiet=True)
            lvc_converter.convert(str(temp_sxs_path), temp_dir, truncation_tol=truncation_tol)
            error_count = sxs.utilities.lvcnr.compare(str(temp_path / shortest_lvcnr), str(temp_sxs_path))
            assert error_count == 0


from typing import List
class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        n = len(prices)
        if n <= 1: return 0
        prices.insert(0, 0)
        MP = [[0] * 2 for _ in range(n + 1)]
        MP[0][1] = float('-inf')
        for i in range(1, n + 1):
            MP[i][0] = max(MP[i - 1][0], MP[i - 1][1] + prices[i])
            MP[i][1] = max(MP[i - 1][1], MP[i - 1][0] - prices[i] -fee)
        return MP[n][0]


import requests, os, pytest
from locuszoom.api import create_app

@pytest.fixture
def client():
  app = create_app()
  client = app.test_client()
  return client

def test_statistic_single_experiment(client):
  resp = client.get("/v1/statistic/single/")
  assert resp.status_code == 200

  for k in "analysis build date first_author last_author id imputed pmid study tech trait".split():
    assert k in resp.json["data"]
    assert len(resp.json["data"][k]) > 1


import numpy as np
import matplotlib.pyplot as plt

path = r'D:\data\20201228\190937_cavity_bare_freq_without_pi_bright'
data_name = path+path[16:]+r'.dat'
data_bare = np.loadtxt(data_name, unpack=True)

freq_bare = data_bare[0][0]
power_bare = data_bare[1]
absol_bare = data_bare[2]

path = r'D:\data\20201228\190527_cavity_bare_freq_with_pi_bright'
data_name = path+path[16:]+r'.dat'
data_pi = np.loadtxt(data_name, unpack=True)

absol_pi = data_pi[2]

# print(pow_arr)
# plt.plot(freq, absol[-1])
# plt.title(path[8:])
plt.plot(power_bare, 20*np.log10(np.array(absol_pi)), 'b.', label = 'pi')
plt.plot(power_bare, 20*np.log10(np.array(absol_bare)), 'r.', label = 'bare')
plt.xlabel('Power (dBm)')
plt.ylabel('Voltage')
plt.legend()
# plt.colorbar()
plt.show()


import datetime
import requests
from metadata_validation_conversion.constants import SAMPLES_ALLOWED_SPECIAL_SHEET_NAMES, ADDITIONAL_INFO_MAPPING, \
     SUBMISSION_TEST_SERVER, SUBMISSION_PROD_SERVER
from validation.helpers import get_record_name
from submission.helpers import remove_underscores
from .helpers import get_header

class BiosamplesFileConverter:
    def __init__(self, json_to_convert, private, mode, action):
        self.json_to_convert = json_to_convert
        self.private_submission = private
        self.action = action
        self.submission_server = SUBMISSION_TEST_SERVER if mode == 'test' else SUBMISSION_PROD_SERVER

    def start_conversion(self):
        data_to_send = list()
        taxon_ids, taxons = self.get_taxon_information()
        collection_date, geographic_location = self.get_ena_required_information()

        # If private submission move date for two years in the future
        if self.private_submission:
            two_years = datetime.timedelta(days=365) * 2
            date = (datetime.datetime.now() + two_years).isoformat()
        else:
            date = datetime.datetime.now().isoformat()

        # Collect additional data, submission information
        additional_fields = dict()
        for additional_field in SAMPLES_ALLOWED_SPECIAL_SHEET_NAMES:
            if additional_field in ['person', 'organization']:
                continue
            for item in self.json_to_convert[additional_field]:
                for existing_field, existing_value in item.items():
                    additional_fields.setdefault(
                        remove_underscores(existing_field), list())
                    additional_fields[remove_underscores(
                        existing_field)].append({'text': existing_value})

        organization_info = self.get_additional_data('organization')
        person_info = self.get_additional_data('person')
        for record_type, records in self.json_to_convert.items():
            if record_type in SAMPLES_ALLOWED_SPECIAL_SHEET_NAMES:
                continue
            for record_index, record in enumerate(records):
                record_name = get_record_name(record, record_index, record_type, self.action)
                data_to_send.append(
                    {
                        "name": record_name,
                        "release": date,
                        "contact": person_info,
                        "organization": organization_info,
                        "characteristics": self.get_sample_attributes(
                            record, additional_fields, taxon_ids, taxons,
                            record_name, collection_date, geographic_location),
                        "relationships": self.get_sample_relationships(
                            record, record_name)
                    }
                )
        return data_to_send

    def get_ena_required_information(self):
        collection_date = dict()
        geographic_location = dict()
        missing_ids = dict()
        for record_type, records in self.json_to_convert.items():
            if record_type in SAMPLES_ALLOWED_SPECIAL_SHEET_NAMES:
                continue
            for record_index, record in enumerate(records):
                record_name = get_record_name(record, record_index, record_type, self.action)
                if 'specimen_collection_date' in record and 'geographic_location' in record:
                    collection_date[record_name] = record['specimen_collection_date']['value']
                    geographic_location[record_name] = record['geographic_location']['value']
                elif 'derived_from' in record:
                    if isinstance(record['derived_from'], dict):
                        missing_ids[record_name] = record['derived_from']['value']
                    elif isinstance(record['derived_from'], list):
                        missing_ids[record_name] = record['derived_from'][0]['value']
        for id_to_fetch in missing_ids:
            collection_date[id_to_fetch], geographic_location[id_to_fetch] = self.fetch_ena_required_information(
                id_to_fetch, collection_date, geographic_location, missing_ids)
        return collection_date, geographic_location

    def fetch_ena_required_information(self, id_to_fetch, collection_date, geographic_location, missing_ids):
        if id_to_fetch in collection_date and id_to_fetch in geographic_location:
            return collection_date[id_to_fetch], geographic_location[id_to_fetch]
        else:
            # TODO: return error in taxon is not in biosamples
            # check that id is Biosample id
            if 'SAM' in id_to_fetch and '_' not in id_to_fetch:
                try:
                    results = requests.get(f"https://www.ebi.ac.uk/biosamples/samples/{id_to_fetch}").json()
                    if ('collection date' in results['characteristics'] and
                            'geographic location (country and/or sea)' in results['characteristics']):
                        return (results['characteristics']['collection date'][0]['text'],
                                results['characteristics']['geographic location (country and/or sea)'][0]['text'])
                    else:
                        return 'not collected', 'not collected'
                except ValueError:
                    pass
                except KeyError:
                    results = requests.get(f"https://www.ebi.ac.uk/biosamples/samples/{id_to_fetch}",
                                           headers=get_header()).json()
                    return results['characteristics']['collection date'][0]['text'],\
                        results['characteristics']['geographic location (country and/or sea)'][0]['text']
            else:
                return self.fetch_ena_required_information(missing_ids[id_to_fetch], collection_date,
                                                           geographic_location, missing_ids)

    def get_taxon_information(self):
        """
        This function will parse whole json to get all taxon ids
        :return: dict with id as key and taxon id as value
        """
        taxon_ids = dict()
        taxons = dict()
        missing_ids = dict()
        for record_type, records in self.json_to_convert.items():
            if record_type in SAMPLES_ALLOWED_SPECIAL_SHEET_NAMES:
                continue
            for record_index, record in enumerate(records):
                record_name = get_record_name(record, record_index, record_type, self.action)
                if 'organism' in record:
                    taxon_ids[record_name] = record['organism']['term']
                    taxons[record_name] = record['organism']['text']
                elif 'derived_from' in record:
                    if isinstance(record['derived_from'], dict):
                        missing_ids[record_name] = record['derived_from']['value']
                    elif isinstance(record['derived_from'], list):
                        missing_ids[record_name] = record['derived_from'][0]['value']
        for id_to_fetch in missing_ids:
            taxon_ids[id_to_fetch], taxons[id_to_fetch] = \
                self.fetch_taxon_information(id_to_fetch, taxon_ids,
                                             taxons, missing_ids)
        return taxon_ids, taxons

    def fetch_taxon_information(self, id_to_fetch, taxon_ids, taxons,
                                missing_ids):
        """
        This function will find taxon id for particular record
        :param id_to_fetch: id to check
        :param taxon_ids: existing taxon ids
        :param taxons: existing taxons
        :param missing_ids: missing taxon ids
        :return:
        """
        if id_to_fetch in taxon_ids and id_to_fetch in taxons:
            return taxon_ids[id_to_fetch], taxons[id_to_fetch]
        else:
            # TODO: return error in taxon is not in biosamples
            # check that id is Biosample id
            if 'SAM' in id_to_fetch and '_' not in id_to_fetch:
                try:
                    results = requests.get(
                        f"{SUBMISSION_PROD_SERVER}/biosamples/samples/"
                        f"{id_to_fetch}").json()
                    return results['taxId'], results['characteristics'][
                        'organism'][0]['text']
                except ValueError:
                    pass
                except KeyError:
                    results = requests.get(
                        f"https://www.ebi.ac.uk/biosamples/samples/"
                        f"{id_to_fetch}", headers=get_header()).json()
                    return results['taxId'], results['characteristics'][
                        'organism'][0]['text']
            else:
                return self.fetch_taxon_information(missing_ids[id_to_fetch],
                                                    taxon_ids,
                                                    taxons,
                                                    missing_ids)

    def get_additional_data(self, key):
        additional_data = list()
        for item in self.json_to_convert[key]:
            tmp = dict()
            for existing_field, existing_value in item.items():
                tmp[ADDITIONAL_INFO_MAPPING[existing_field]] = existing_value
            additional_data.append(tmp)
        return additional_data

    @staticmethod
    def get_sample_relationships(record, record_name):
        """
        This function will parse record and find all relationships
        :param record: record to parse
        :param record_name: name of the current record
        :return: list of all relationships
        """
        sample_relationships = list()
        if 'same_as' in record:
            sample_relationships.append(
                {
                    "source": record_name,
                    "type": "same as",
                    "target": record['same_as']['value']
                }
            )
        if 'child_of' in record:
            for child in record['child_of']:
                sample_relationships.append(
                    {
                        "source": record_name,
                        "type": "child of",
                        "target": child['value']
                    }
                )
        if 'derived_from' in record:
            if isinstance(record['derived_from'], list):
                for child in record['derived_from']:
                    sample_relationships.append(
                        {
                            "source": record_name,
                            "type": "derived from",
                            "target": child['value']
                        }
                    )
            elif isinstance(record['derived_from'], dict):
                sample_relationships.append(
                    {
                        "source": record_name,
                        "type": "derived from",
                        "target": record['derived_from']['value']
                    }
                )
        return sample_relationships

    def get_sample_attributes(self, record, additional_fields, taxon_ids,
                              taxons, record_name, collection_date, geographic_location):
        """
        This function will return biosample attributes
        :param record: record to parse
        :param additional_fields: additional fields to add to dict
        :param taxon_ids: dict with taxon ids
        :param taxons: dict with taxon names
        :param record_name: name of the current record
        :return: attributes for this record in biosample format
        """
        sample_attributes = dict()
        for attribute_name, attribute_value in record.items():
            if attribute_name == 'samples_core':
                for sc_attribute_name, sc_attribute_value in \
                        record['samples_core'].items():
                    sample_attributes[remove_underscores(sc_attribute_name)] = \
                        self.parse_attribute(sc_attribute_value)
            elif attribute_name == 'custom':
                for sc_attribute_name, sc_attribute_value in \
                        record['custom'].items():
                    sample_attributes[remove_underscores(sc_attribute_name)] = \
                        self.parse_attribute(sc_attribute_value)
            elif attribute_name == 'teleostei_post-hatching':
                for sc_attribute_name, sc_attribute_value in \
                        record['teleostei_post-hatching'].items():
                    sample_attributes[remove_underscores(sc_attribute_name)] = \
                        self.parse_attribute(sc_attribute_value)
            elif attribute_name == 'teleostei_embryo':
                for sc_attribute_name, sc_attribute_value in \
                        record['teleostei_embryo'].items():
                    sample_attributes[remove_underscores(sc_attribute_name)] = \
                        self.parse_attribute(sc_attribute_value)
            elif attribute_name == 'geographic_location':
                continue
            else:
                sample_attributes[remove_underscores(attribute_name)] = \
                    self.parse_attribute(attribute_value)
        sample_attributes.update(additional_fields)
        # BioSamples require for every sample to have organism object
        if 'organism' not in sample_attributes:
            if ':' in str(taxon_ids[record_name]):
                taxon_id = "_".join(taxon_ids[record_name].split(":"))
            else:
                # Need this to create appropriate taxon id from BioSamples id
                taxon_id = f"NCBITaxon_{taxon_ids[record_name]}"
            organism_object = {
                'text': taxons[record_name],
                'ontologyTerms': [f"http://purl.obolibrary.org/obo/{taxon_id}"]
            }
            sample_attributes['organism'] = [organism_object]
        if self.private_submission:
            sample_attributes['BovReg private submission'] = [{'text': 'TRUE'}]

        if record_name in collection_date and record_name in geographic_location:
            sample_attributes['collection date'] = [{'text': collection_date[record_name], 'tag': 'attribute'}]
            sample_attributes['geographic location (country and/or sea)'] = [
                {'text': geographic_location[record_name], 'tag': 'attribute'}]
        return sample_attributes

    def parse_attribute(self, value_to_parse):
        """
        This function will parse single attribute from data
        :param value_to_parse: data to parse
        :return: attributes list
        """
        attributes = list()

        if isinstance(value_to_parse, list):
            for sc_value_to_parse in value_to_parse:
                attributes.append(
                    self.parse_value_in_attribute(sc_value_to_parse)
                )
        elif isinstance(value_to_parse, dict):
            attributes.append(
                self.parse_value_in_attribute(value_to_parse)
            )
        return attributes

    @staticmethod
    def parse_value_in_attribute(value_to_parse):
        """
        This function will parse single fields
        :param value_to_parse: field to parse
        :return: dict of attributes
        """
        attribute = dict()
        if 'text' in value_to_parse:
            attribute['text'] = value_to_parse['text']
        elif 'value' in value_to_parse:
            attribute['text'] = value_to_parse['value']

        if 'term' in value_to_parse:
            ontology_url = "_".join(value_to_parse['term'].split(":"))
            attribute['ontologyTerms'] = [
                f"http://purl.obolibrary.org/obo/{ontology_url}"]

        if 'units' in value_to_parse:
            attribute['unit'] = value_to_parse['units']
        return attribute


import torch
from pypet import cartesian_product, Trajectory, Parameter, ParameterGroup
from pypet_experiments.gather import gather_results_to_DataFrame, gather_parameters_to_DataFrame
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
import pandas as pd
import numpy as np
from matplotlib.lines import Line2D

torch.set_default_tensor_type(torch.cuda.FloatTensor)
plt.rcParams.update(plt.rcParamsDefault)
sns.set_theme(style="whitegrid", palette="colorblind")
plt.rcParams.update({
    "text.usetex": False,
    "mathtext.default": "regular",
    "font.family": ["sans-serif"],
    "font.sans-serif": ["Lato"],
    "axes.labelweight": "normal",
    "figure.titleweight": "bold",
    "figure.titlesize": "large",
    "font.weight": "normal",
    # "axes.formatter.use_mathtext": True,
    "xtick.labelsize": 9,
    "ytick.labelsize": 9,
})

# Methods
methods = {
    # "Oracle":           ("Oracle",      "#000000", "solid", "s"),

    "VMP":              ("NAIVI-VMP",   "#1111ff", "solid", "o"),
    # "ADVI":             ("NAIVI-QB",    "#8888ff", "dashed", "v"),

    "MAP":              ("NAIVI-MAP",   "#3333ff", "dotted", "s"),
    # "MLE":              ("NAIVI-MLE",   "#3333ff", "dotted", "v"),
    "NetworkSmoothing": ("Smoothing",   "#8888ff", "dashed", "s"),

    # "FA":               ("FA",          "#88ffcc", "dotted", "o"),
    # "KNN":              ("KNN",         "#88ff88", "dashed", "v"),
    # "MICE":             ("MICE",        "#88ff88", "dashed", "s"),

    # "Mean":             ("Mean",        "#55cc55", "dotted", "s"),
}

name = "email"
res_list = []
for i in range(31):
    file = f"./experiments/{name}/results/seed{i}.hdf5"
    traj = Trajectory(name=name)
    traj.f_load(filename=file, load_results=2, force=True)

    parameters = gather_parameters_to_DataFrame(traj)
    results = gather_results_to_DataFrame(traj)
    results = parameters.join(results)
    res_list.append(results)

results = pd.concat(res_list)

metrics = {
    "testing.auroc_multiclass": ("Multiclass AuROC", ),
    "testing.f1_multiclass_micro": ("F1 (micro)", ),
    "testing.f1_multiclass_macro": ("F1 (macro)", ),
    "testing.accuracy_multiclass": ("Accuracy (%)", ),
}

fig, axs = plt.subplots(1, len(metrics), figsize=(10, 4), sharey=False)

for i, (metric, (metric_name, )) in enumerate(metrics.items()):
    ax = axs[i]

    for i, (method, (method_name, color, linestyle, marker)) in enumerate(methods.items()):
        res_method = results.loc[results["method"] == method]
        ys = res_method.groupby("data.n_seeds").agg(
            median=(metric, "median"),
            lower=(metric, lambda x: np.quantile(x, 0.25)),
            upper=(metric, lambda x: np.quantile(x, 0.75)),
        )
        xs = ys.index

        ax.plot(xs, ys["median"], color=color, linestyle=linestyle,
                marker=marker, label=method_name, markerfacecolor='none')
        ax.fill_between(xs, ys["lower"], ys["upper"], color=color, alpha=0.2)

    ax.set_title(f"{metric_name}")
    ax.set_xlabel("Seeds / Dpt.", size=10)
    ax.set_xticks([2, 4, 6, 8, 10])
# legend
lines = [Line2D([0], [0], color=color, linestyle=ltype, marker=mtype, markerfacecolor='none')
         for _, (_, color, ltype, mtype) in methods.items()]
labels = [name for _, (name, _, _, _) in methods.items()]
fig.legend(lines, labels, loc=9, ncol=6)
plt.tight_layout()
fig.subplots_adjust(top=0.80)
# plt.show()

plt.savefig(f"./experiments/{name}/metrics.pdf")


import hashlib
import hmac

from decouple import config
from django.http import HttpResponse
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView

from ..tasks import update_thread_from_webhook_delta

def verify_signature(message, key, signature):
    """
    This function will verify the authenticity of a digital signature.
    For security purposes, Nylas includes a digital signature in the headers
    of every webhook notification, so that clients can verify that the
    webhook request came from Nylas and no one else. The signing key
    is your OAuth client secret, which only you and Nylas know.
    """
    try:
        digest = hmac.new(key, msg=message, digestmod=hashlib.sha256).hexdigest()
        return hmac.compare_digest(digest, signature)
    except Exception as e:
        print(e)
        return False

class NylasWebhookView(APIView):
    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        challenge = request.query_params.get('challenge', None)
        return HttpResponse(content=challenge, status=200)

    def post(self, request, *args, **kwargs):
        genuine = verify_signature(
            message=request.body,
            key=config('NYLAS_CLIENT_SECRET', cast=str).encode("utf8"),
            signature=request.META.get('HTTP_X_NYLAS_SIGNATURE', None),
        )
        if not genuine:
            return HttpResponse(content='Signature verification failed!', status=401)
        # process deltas
        deltas = request.data.get('deltas', [])
        for delta in deltas:
            account_id = delta.get('object_data', {}).get('account_id', None)
            thread_id = delta.get('object_data', {}).get('attributes', {}).get('thread_id', None)
            update_thread_from_webhook_delta.delay(account_id, thread_id)
        return HttpResponse(content='Deltas have been queued', status=200)


from slimit import ast

class JSBase:

    def __init__(self, node):
        self.node = node

    def __str__(self):
        if isinstance(self.node, ast.Boolean):
            return str(self.node.value).lower()
        if isinstance(self.node, ast.Number):
            return str(self.node.value)
        return self.node.to_ecma()

class JSValue(JSBase):

    def __init__(self, node):
        if isinstance(node, ast.Node):
            self.node = node
        elif isinstance(node, bool):
            self.node = ast.Boolean(node)
        elif isinstance(node, (int, float)):
            self.node = ast.Number(node)
        else:
            raise AttributeError('Not a real value, babycakes')

    def __eq__(self, other):
        if isinstance(other, ast.Node):
            return self.node.value == other.value
        else:
            return self.node.value == other

class JSString(JSBase):

    def __init__(self, node):
        if isinstance(node, ast.String):
            self.node = node
        elif isinstance(node, str):
            self.node = ast.String("'{}'".format(node))

    def __eq__(self, other):
        if isinstance(other, str):
            return self.node.value[1:-1] == other
        elif isinstance(other, ast.String):
            return self.node.value[1:-1] == other.value[1:-1]
        return False

class JSArray(JSBase):

    def __init__(self, node):
        if isinstance(node, ast.Array):
            self.node = node
        elif isinstance(node, list):
            self.node = ast.Array([
                PY_MAPPING[v.__class__](v).node for v in node
            ])
        else:
            raise AttributeError('node must be an Array')

    def __getitem__(self, key):
        pass

    def __setitem__(self, key, value):
        pass

class JSObject(JSBase):

    def __init__(self, node):

        if isinstance(node, ast.Object):
            self.node = node
        elif isinstance(node, dict):
            self.node = ast.Object(properties=[
                ast.Assign(
                    op=':',
                    left=PY_MAPPING[k.__class__](k).node,
                    right=PY_MAPPING[v.__class__](v).node
                ) for (k, v) in node.items()
            ])
        else:
            raise AttributeError('node must be an Object')

    def __getitem__(self, key):
        for child in self.node.children():
            if wrapped_ast(child.left) == key:
                cls = AST_MAPPING[child.right.__class__]
                return cls(child.right)
        else:
            raise KeyError(key)

    def __setitem__(self, key, value):
        for child in self.node.children():
            if wrapped_ast(child.left) == key:
                break
        else:
            child = ast.Assign(
                op=':',
                left=PY_MAPPING[key.__class__](key).node,
                right=None
            )
            self.node.properties.append(child)

        child.right = PY_MAPPING[value.__class__](value).node

    def __contains__(self, key):
        try:
            self[key]
        except KeyError:
            return False
        else:
            return True

    def keys(self):
        for child in self.node.children():
            if isinstance(child.left, ast.String):
                yield child.left.value[1:-1]
            else:
                yield child.left.value

AST_MAPPING = {
    ast.Object: JSObject,
    ast.Array: JSArray,
    ast.Number: JSValue,
    ast.String: JSString,
    ast.Boolean: JSValue
}

PY_MAPPING = {
    bool: JSValue,
    float: JSValue,
    int: JSValue,
    str: JSString,
    dict: JSObject,
    list: JSArray
}
JS_MAPPING = dict((v, k) for k, v in PY_MAPPING.items())

def wrapped_ast(node):
    return AST_MAPPING.get(node.__class__, JSValue)(node)


import logging
import allure
from allure_commons.types import AttachmentType

class SearchResultsPage:

    def __init__(self,driver):
        self.driver = driver
        self.hotel_names_xpath = "//h4[contains(@class,'list_title')]//b"
        self.hotel_prices_xpath = "//div[contains(@class,'price_tab')]//b"
        self.logger = logging.getLogger(__name__)

#Creating hotel name list with raport description
    @allure.step("Getting hotel names")
    def get_hotel_names(self):

        hotels = self.driver.find_elements_by_xpath(self.hotel_names_xpath)
        names =  [hotel.get_attribute("textContent") for hotel in hotels]
        self.logger.info("Available hotels are:")
        allure.attach(self.driver.get_screenshot_as_png(), name="Hotel names", attachment_type=AttachmentType.PNG)
        for name in names:
            self.logger.info(name)
        return names

#Creating hotel price list with raport description
    @allure.step("Getting hotel prices")
    def get_hotel_prices(self):
        prices = self.driver.find_elements_by_xpath(self.hotel_prices_xpath)
        hotel_prices =   [price.get_attribute("textContent") for price in prices]
        self.logger.info("Prices of available hotels are:")
        allure.attach(self.driver.get_screenshot_as_png(), name="Hotel prices", attachment_type=AttachmentType.PNG)
        for hotel in hotel_prices:
            self.logger.info(hotel)
        return hotel_prices


import spacy

# Example 1
nlp = spacy.load('en_core_web_md')

word1 = nlp("cat")
word2 = nlp("monkey")
word3 = nlp("banana")

# Code compares similarity of words
# It's intersting that cat and monkey have the highest similarity as they are
# animals, and banana and monkey have higher similarity than banana and cat,
# assumedly due to the stronger association of banana with monkey rather than cat
print(word1.similarity(word2))
print(word3.similarity(word2))
print(word3.similarity(word1))

# Example 2
tokens = nlp('cat apple monkey banana ')

for token1 in tokens:
    for token2 in tokens:
        print(token1.text, token2.text, token1.similarity(token2))

# Example 3
sentence_to_compare = "Why is my cat on the car"

sentences = ["where did my dog go",
"Hello, there is my car",
"I\'ve lost my car in my car",
"I\'d like my boat back",
"I will name my dog Diana"]

model_sentence = nlp(sentence_to_compare)

for sentence in sentences:
    similarity = nlp(sentence).similarity(model_sentence)
    print(sentence + " - ", similarity)