import unittest
import numpy as np
from datetime import datetime, timedelta
from hagelslag.data.ModelOutput import ModelOutput
from hagelslag.processing.tracker import label_storm_objects, extract_storm_objects, extract_storm_patches
from hagelslag.processing.TrackProcessing import TrackProcessor
from hagelslag.processing.ObjectMatcher import shifted_centroid_distance, centroid_distance, time_distance
import os

class TestTracking(unittest.TestCase):
    def setUp(self):
        current_dir_files = os.listdir("./")
        if "testdata" not in current_dir_files:
            start_path = "../"
        else:
            start_path = "./"
        self.model_path = start_path + "testdata/spring2015_unidata/"
        self.ensemble_name = "SSEF"
        self.member ="wrf-s3cn_arw"
        self.run_date = datetime(2015, 6, 4)
        self.variable = "uh_max"
        self.start_hour = 18
        self.end_hour = 24
        self.start_date = self.run_date + timedelta(hours=self.start_hour)
        self.end_date = self.run_date + timedelta(hours=self.end_hour)
        self.map_file = start_path + "mapfiles/ssef2015.map"
        self.model_grid = ModelOutput(self.ensemble_name,
                                 self.member,
                                 self.run_date,
                                 self.variable,
                                 self.start_date,
                                 self.end_date,
                                 self.model_path,
                                 self.map_file,
                                 single_step=False)
        self.model_grid.load_data()
        self.model_grid.load_map_info(self.map_file)

    def test_model_grid_loading(self):
        print(self.model_grid.lat.shape, self.model_grid.lon.shape)
        self.assertEqual(self.model_grid.lat.shape[0], self.model_grid.lon.shape[0],
                          "Lat and Long grids are not equal shaped. {")
        self.assertEqual(self.model_grid.data.shape[1:], self.model_grid.lat.shape,
                          "Data shape does not match map shape.")
        self.assertEqual(self.end_hour - self.start_hour + 1, self.model_grid.data.shape[0],
                          "Number of hours loaded does not match specified hours.")

    def test_object_identification(self):
        min_thresh = 10
        max_thresh = 50
        label_grid = label_storm_objects(self.model_grid.data[0], "hyst",
                                         min_thresh, max_thresh, min_area=2, max_area=100)
        label_points = self.model_grid.data[0][label_grid > 0]
        self.assertGreaterEqual(label_points.min(), min_thresh, "Labeled points include those below minimum threshold")
        storm_objs = extract_storm_objects(label_grid, self.model_grid.data[0], self.model_grid.x,
                                           self.model_grid.y, np.array([0]))
        self.assertEqual(len(storm_objs[0]), label_grid.max(), "Storm objects do not match number of labeled objects")
        storm_patch_objs = extract_storm_patches(label_grid, self.model_grid.data[0], self.model_grid.x,
                                                 self.model_grid.y, np.array([0]))
        self.assertEqual(len(storm_patch_objs[0]), len(storm_objs[0]), "Full object and patch extraction counts don't match.")

    def test_track_processing(self):
        ws_params = (25, 50)
        object_matcher_params = ([shifted_centroid_distance], np.array([1.0]),
                             np.array([24000]))
        track_matcher_params = ([centroid_distance, time_distance],
                                     np.array([80000, 2]))
        size_filter = 10
        gaussian_window = 1
        tp = TrackProcessor(self.run_date, self.start_date, self.end_date, self.ensemble_name,
                            self.member, self.variable, self.model_path, self.map_file, ws_params,
                            object_matcher_params, track_matcher_params, size_filter, gaussian_window,
                            segmentation_approach="ws", single_step=False
                            )
        track_model_patch_objects = tp.find_model_patch_tracks()
        self.assertGreater(len(track_model_patch_objects), 0, "No patch objects found")
        #track_model_objects = tp.find_model_tracks()
        #self.assertGreater(len(track_model_objects), 0, "No objects found")


def addV(*args):
    sides=len(args)
    print('There are',sides,'sides to the object')
    total=0
    for i in range(0,sides):
        total=total +args[i]
    return total

object1 = addV(2,3,4)
print('the object1 total is:',object1)

object2 = addV(2,3,4,5)
print('the object2 total is:',object2)

object3 = addV(2,3,4,5,10)
print('the object3 total is:',object3)


import os
import cv2
import numpy as np
import random
from pycocotools.coco import COCO

import torch
from torch.utils.data import Dataset

dataset_path = '/opt/ml/input/data'
category_names = ['Background', 'UNKNOWN', 'General trash', 'Paper', 'Paper pack', 'Metal',
                    'Glass', 'Plastic', 'Styrofoam', 'Plastic bag', 'Battery', 'Clothing']

def get_classname(classID, cats):
    for i in range(len(cats)):
        if cats[i]['id'] == classID:
            return cats[i]['name']
    return "None"

class RecycleTrashDataset(Dataset):
    """Some Information about RecycleTrashDataset"""
    def __init__(self, data_dir, mode='train', transform=None, augmix=None, augmix_prob=0):
        super().__init__()
        self.mode = mode
        self.transform = transform
        self.augmix = augmix
        self.augmix_prob = augmix_prob
        self.coco = COCO(os.path.join(dataset_path, data_dir))

    def __getitem__(self, index: int):
        # dataset이 index되어 list처럼 동작
        image_id = self.coco.getImgIds(imgIds=index)
        image_infos = self.coco.loadImgs(image_id)[0]

        # cv2 를 활용하여 image 불러오기
        images = cv2.imread(os.path.join(dataset_path, image_infos['file_name']))
        images = cv2.cvtColor(images, cv2.COLOR_BGR2RGB).astype(np.uint8)

        if (self.mode in ('train', 'val')):
            ann_ids = self.coco.getAnnIds(imgIds=image_infos['id'])
            anns = self.coco.loadAnns(ann_ids)

            # Load the categories in a variable
            cat_ids = self.coco.getCatIds()
            cats = self.coco.loadCats(cat_ids)

            # masks : size가 (height x width)인 2D
            # 각각의 pixel 값에는 "category id + 1" 할당
            # Background = 0
            masks = np.zeros((image_infos["height"], image_infos["width"]))
            # Unknown = 1, General trash = 2, ... , Cigarette = 11
            for i in range(len(anns)):
                className = get_classname(anns[i]['category_id'], cats)
                pixel_value = category_names.index(className)
                masks = np.maximum(self.coco.annToMask(anns[i]) * pixel_value, masks)
            masks = masks.astype(np.float32)

            # one-hot
            target = np.unique(masks).astype(int)
            one_hot_label = np.sum(np.eye(12)[target], axis=0)

            # img, mask 다 np , 512x512
            if self.augmix is not None :
              r = np.random.rand(1)
              if r < self.augmix_prob :
                  images , masks = self.augmix_search(images , masks)

            # transform -> albumentations 라이브러리 활용
            if self.transform is not None:
                transformed = self.transform(image=images, mask=masks)
                images = transformed["image"]
                masks = transformed["mask"]

            return images, masks, torch.Tensor(one_hot_label), image_infos

        if self.mode == 'test':
            # transform -> albumentations 라이브러리 활용
            if self.transform is not None:
                transformed = self.transform(image=images)
                images = transformed["image"]

            return images, image_infos

    def __len__(self) -> int:
        # 전체 dataset의 size를 return
        return len(self.coco.getImgIds())

    def augmix_search(self, images, masks):
        # image 3, 512, 512 ,mask: 512, 512 (둘 다 numpy)
        temp_dict = {
        0: 4, 1: 5, 2: 6, 3: 10, 4: 11
        }
        num = [ 4, 5, 6, 10, 11]

        label = random.choice(num)  # ex) 4
        idx = np.random.randint(len(self.augmix[label]))
        augmix_img = self.augmix[label][idx]

        augmix_mask = np.zeros((512, 512))
        augmix_mask[augmix_img[:, :, 0] != 0] = label     # augmix img가 있는 만큼 label로 mask를 채워줌

        images[augmix_img != 0] = augmix_img[augmix_img != 0]
        masks[augmix_mask!= 0] = augmix_mask[augmix_mask != 0]

        return images, masks

import pandas as pd
import albumentations as A

class PseudoDataset(Dataset):
    def __init__(self, data_dir='/opt/ml/input/data/', pseudo_csv='presudo_result.csv', transform=None):
        self.data_dir = data_dir
        self.df = pd.read_csv(os.path.join(data_dir, pseudo_csv))
        self.tfms = A.Resize(512, 512, interpolation= cv2.INTER_NEAREST)

        self.transform = transform

    def __len__(self):
        return len(self.df)

    def __getitem__(self, idx):
        img_path = self.df.iloc[idx, 0]
        img_path = os.path.join(self.data_dir, img_path)
        mask = self.df.iloc[idx, 1]
        mask = np.array(list(map(int, mask.split())))
        mask = mask.reshape(256, 256)
        mask = self.tfms(image=mask)['image']

        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.uint8)

        # one-hot
        target = np.unique(mask).astype(int)
        one_hot_label = np.sum(np.eye(12)[target], axis=0)

        if self.transform is not None:
            transformed = self.transform(image=img, mask=mask)
            images = transformed["image"]
            masks = transformed["mask"]

        return images, masks, torch.Tensor(one_hot_label), img_path

class AllDataset(Dataset):
    def __init__(self, data_dir, mode='train', augmix_prob=0.15, augmix=None, transform=None):
        self.presudo_transform = A.Compose([
            A.Resize(512, 512),
            A.Normalize(mean=(0.461, 0.440, 0.419), std=(0.211, 0.208, 0.216)),
            A.pytorch.transforms.ToTensorV2()
        ])
        self.presudo_ds = PseudoDataset(transform=self.presudo_transform)
        self.seg_ds = RecycleTrashDataset(data_dir=data_dir, mode=mode, augmix=augmix, augmix_prob=augmix_prob, transform=transform)

    def __len__(self):
        return len(self.presudo_ds) + len(self.seg_ds)

    def __getitem__(self, idx):
        if idx >= len(self.seg_ds):
            return self.presudo_ds.__getitem__(idx - len(self.seg_ds))
        else:
            return self.seg_ds.__getitem__(idx)


import requests
import re

class ThreadsAPI:
    fbLSDToken = 'NjppQDEgONsU_1LCzrmp6q' # FIXME: Remove default value

    def __init__(self, options=None):
        if options and 'fbLSDToken' in options:
            self.fbLSDToken = options['fbLSDToken']

    def _get_default_headers(self, username):
        return {
            'authority': 'www.threads.net',
            'accept': '*/*',
            'accept-language': 'ko,en;q=0.9,ko-KR;q=0.8,ja;q=0.7',
            'cache-control': 'no-cache',
            'origin': 'https://www.threads.net',
            'pragma': 'no-cache',
            'referer': f'https://www.threads.net/@{username}',
            'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1',
            'x-asbd-id': '129477',
            'x-fb-lsd': self.fbLSDToken,
            'x-ig-app-id': '238260118697367'
        }

    def get_user_id_from_username(self, username):
        headers = self._get_default_headers(username)
        headers['referer'] = 'https://www.instagram.com/'

        response = requests.get(f'https://www.threads.net/@{username}', headers=headers)
        text = response.text.replace('\n', '')

        user_id = re.search(r'"props":{"user_id":"(\d+)"},', text)
        if user_id:
            return user_id.group(1)
        else:
            return None

    def get_user_profile(self, username, user_id=None):
        """
            Requires username and as an optional parameter user_id.
            If no user_id is passed then the function will automatically get user_id by
            resolving username.
        """
        if not user_id:
            user_id = self.get_user_id_from_username(username)
        headers = self._get_default_headers(username)
        headers['x-fb-friendly-name'] = 'BarcelonaProfileRootQuery'

        params = {
            'av': '0',
            '__user': '0',
            '__a': '1',
            '__req': '1',
            '__hs': '19544.HYP:barcelona_web_pkg.2.1..0.0',
            'dpr': '1',
            '__ccg': 'EXCELLENT',
            '__rev': '1007795914',
            '__s': 'c1fpxh:oh98tm:os2fqi',
            '__hsi': '7252655495199472548',
            '__dyn': '7xeUmwlEnwn8K2WnFw9-2i5U4e0yoW3q32360CEbo1nEhw2nVE4W0om78b87C0yE465o-cw5Mx62G3i0Bo7O2l0Fwqo31wnEfovwRwlE-U2zxe2Gew9O22362W2K0zK5o4q0GpovU1aUbodEGdwtU2ewbS1LwTwNwLw8O1pwr82gxC',
            '__csr': 'j8kjt5p9e00hB4Eqw-w0Xiwrk0xE9Eixza2svazUndhEpko9xy7Ej7Saxl2U5-8m8yA4zCwxxWegQz5162a5x02UxW1g2Ex3MwM_3M25wlQ13gN0el4m2H3r16089wxwnq0w8gqd12',
            '__comet_req': '29',
            'lsd': self.fbLSDToken,
            'jazoest': '21997',
            '__spin_r': '1007795914',
            '__spin_b': 'trunk',
            '__spin_t': '1688640447',
            '__jssesw': '2',
            'fb_api_caller_class': 'RelayModern',
            'fb_api_req_friendly_name': 'BarcelonaProfileRootQuery',
            'variables': f'{{"userID":"{user_id}"}}',
            'server_timestamps': 'true',
            'doc_id': '23996318473300828'
        }

        response = requests.post('https://www.threads.net/api/graphql', params=params, headers=headers)
        user = response.json()['data']['userData']['user']
        return user

    def get_user_profile_threads(self, username, user_id=None):
        """
        Returns user profile threads as a dict

        Args:
            username (string): username on threads.net
            user_id (string, optional): user_id which is unique to each user. Defaults to None.

        Returns:
            dict: list of user profile threads.
        """
        headers = self._get_default_headers(username)
        headers['x-fb-friendly-name'] = 'BarcelonaProfileThreadsTabQuery'

        params = {
            'av': '0',
            '__user': '0',
            '__a': '1',
            '__req': '2',
            '__hs': '19544.HYP:barcelona_web_pkg.2.1..0.0',
            'dpr': '1',
            '__ccg': 'EXCELLENT',
            '__rev': '1007795914',
            '__s': 'c1fpxh:oh98tm:os2fqi',
            '__hsi': '7252655495199472548',
            '__dyn': '7xeUmwlEnwn8K2WnFw9-2i5U4e0yoW3q32360CEbo1nEhw2nVE4W0om78b87C0yE465o-cw5Mx62G3i0Bo7O2l0Fwqo31wnEfovwRwlE-U2zxe2Gew9O22362W2K0zK5o4q0GpovU1aUbodEGdwtU2ewbS1LwTwNwLw8O1pwr82gxC',
            '__csr': 'j8kjt5p9e00hB4Eqw-w0Xiwrk0xE9Eixza2svazUndhEpko9xy7Ej7Saxl2U5-8m8yA4zCwxxWegQz5162a5x02UxW1g2Ex3MwM_3M25wlQ13gN0el4m2H3r16089wxwnq0w8gqd12',
            '__comet_req': '29',
            'lsd': self.fbLSDToken,
            'jazoest': '21997',
            '__spin_r': '1007795914',
            '__spin_b': 'trunk',
            '__spin_t': '1688640447',
            '__jssesw': '2',
            'fb_api_caller_class': 'RelayModern',
            'fb_api_req_friendly_name': 'BarcelonaProfileThreadsTabQuery',
            'variables': f'{{"userID":"{user_id}"}}',
            'server_timestamps': 'true',
            'doc_id': '6232751443445612'
        }

        response = requests.post('https://www.threads.net/api/graphql', params=params, headers=headers)
        threads = response.json()
        print(threads)
        # threads = response.json()['data']['mediaData']['threads']
        return threads


import getSNMP as snmp
import getSNMP2 as snmp2
from Reporte import creandoReporte
from hilo import hiloUpdate
import threading
from time import sleep
from time import time
import rrdtool
from ReporteContabilidad import creandoReporteContabilidad

class Agente():
    comunidad = ''
    ip = ''
    nombreAgente = ''
    sistemaOperativo = ''
    versionSO = ''
    contacto = ''
    ubicacion = ''
    numeroInterfaces = ''
    interfaces = {}
    estado = ''
    snmpVersion = ''
    puerto = ''
    enlace = False
    time = ''
    actualizar = 0
    horario = ''

    def __init__(self):
        self.comunidad = ''
        self.ip = ''
        self.nombreAgente = ''
        self.sistemaOperativo = ''
        self.versionSO = ''
        self.contacto = ''
        self.ubicacion = ''
        self.numeroInterfaces = ''
        self.interfaces = {}
        self.estado = ''
        self.snmpVersion = ''
        self.puerto = ''
        self.enlace = False
        self.time = ''
        self.actualizar = 1
        self.horario = ''

    def obtenerSO(self):
        aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.1.1.0')
        if aux.find("#") > 0:
            if (aux.find("Ubuntu") > 0):  # En caso de ser Ubuntu
                soaux = aux.split()[5]
                ''.join(soaux)
                self.sistemaOperativo = soaux[soaux.find('-') + 1:]
        else:
            self.sistemaOperativo = aux.split()[14]
            self.versionSO = aux.split()[16]

    def obtenerUbicacion(self):
        aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.1.6.0')
        aux = aux.split('=')
        self.ubicacion = aux[-1]

    def obtenerNombre(self):
        aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.1.5.0')
        aux = aux.split('=')
        self.nombreAgente = aux[-1]

    def obtenerContacto(self):
        aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.1.4.0')
        aux = aux.split('=')
        self.contacto = aux[-1]

    def obtenerInterfaces(self):
        aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.2.1.0')
        aux = aux.split('=')
        self.numeroInterfaces = aux[-1]
        i = 1
        while (i <= int(self.numeroInterfaces)):
            aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.2.2.1.8.' + str(i))
            aux = aux.split('=')
            self.interfaces[i] = aux[-1]
            i += 1

    def obtenerHorario(self):
        aux = snmp2.consultaSNMP2(self.comunidad, self.ip, '1.3.6.1.2.1.1.1.0')
        self.horario = aux

    def actualizarHilo(self):
        hilo1 = threading.Thread(args = (self,), target = hiloUpdate)
        hilo1.start()

    """
    def inOctects(self):
        aux = consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.2.2.1.11.1')
        octetosin = aux.split(":")[-1]
    """
    """
    def obtenerEstados(self):
        self.numeroInterfaces = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.2.1.0')
        intEst = []
        for i in range(1, int(self.numeroInterfaces).split('=')):
            aux = snmp.consultaSNMP(self.comunidad, self.ip, '1.3.6.1.2.1.2.2.1.8.' + str(i))
            intEst[i] = aux.split()[4]
            self.estado = intEst[i]
    """
    def crearReporte(self):
        self.obtenerSO()
        self.obtenerContacto()
        self.obtenerUbicacion()
        self.obtenerInterfaces()
        self.obtenerNombre()
        creandoReporte(self)

    def createRRD(self):
        try:
            rrdtool.create(self.ip + '.rrd',
                "--start",'N',
                "--step",'30',
                "DS:unicast:COUNTER:200:U:U",
                "DS:ip:COUNTER:201:U:U",
                "DS:icmp:COUNTER:202:U:U",
                "DS:segmentos:COUNTER:203:U:U",
                "DS:udp:COUNTER:204:U:U",
                "RRA:AVERAGE:0.5:5:300",
                "RRA:AVERAGE:0.5:5:300",
                "RRA:AVERAGE:0.5:5:300",
                "RRA:AVERAGE:0.5:5:300",
                "RRA:AVERAGE:0.5:5:300"
            )
        except Exception as e:
            print("Error al crear el RRD", e)

    def graphRRD(self, tini : int, tfin :  int):
        try :
            i = 0
            for j in ['unicast', 'ip', 'icmp', 'segmentos', 'udp']:
                rrdtool.graph(self.ip + str(i) + ".png",
                             "--start",str(tini),
                             "--end",str(tfin),
                             "--vertical-label="+j,
                            "DEF:"+j+"="+self.ip+".rrd:"+j+":AVERAGE",
                            "AREA:"+j+"#557996:Tramas "+j)
                i += 1
        except Exception as e :
            print("Error al graficar", e)

    def crearReporteContabilidad(self, tinicio : int, tfinal : int ):
        self.obtenerNombre()
        self.obtenerHorario()
        self.obtenerContacto()
        #inOctects(self
        self.graphRRD(tinicio, tfinal)
        creandoReporteContabilidad(self)


#!/usr/bin/env python

"""
API docs:
    https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md
API base URL:
    http://registry.npmjs.com/

extra metrics:
    https://api-docs.npms.io/#api-Package-GetMultiPackageInfo

"""

from __future__ import print_function

import urllib

from .base import *
from stutils import decorators as d

class Package(BasePackage):
    base_url = 'http://registry.npmjs.com/'
    info = None  # stores cached package info

    @classmethod
    def all(cls, cache_file=None):
        if isinstance(cache_file, six.string_types):
            fh = open(cache_file, 'rb')
        elif isinstance(cache_file, six.StringIO):
            fh = cache_file
        else:
            # how to create cache file: wget -O npm.json <url below>
            # it is 14Gb as of Jan 2019
            fh = urllib.urlopen(
                'https://skimdb.npmjs.com/registry/_all_docs?include_docs=true')

        # requires yajl-tools: apt-get install yajl-tools
        import ijson.backends.yajl2 as ijson

        for package_info in ijson.items(fh, 'rows.item'):
            package_name = package_info['id']
            yield Package(package_name, info=package_info['doc'])

    def __init__(self, name, info=None):
        """
        Args:
            name (str): package name.
                Expect it will be normalized to prevent duplicate packages.
            info (Optional[dict]): in some cases (I'm talking about you, npm)
                ecosystem API lists packages with their metadata, so it's
                cheaper to reuse it.
                End users should not use this parameter.
        """
        if info:
            self.info = info
        else:
            try:
                self.info = self._request(name).json()
            except IOError:
                raise PackageDoesNotExist(
                    "Package %s does not exist or not public" % name)

        super(Package, self).__init__(name)

    @d.cached_property
    def _extra_info(self):
        return requests.get(
            "https://api.npms.io/v2/package/" +
            six.moves.urllib.parse.quote_plus(self.name)).json()

    @property
    def quality(self):
        return json_path(self._extra_info, 'score', 'detail', 'quality')

    @property
    def popularity(self):
        return json_path(self._extra_info, 'score', 'detail', 'popularity')

    @property
    def maintenance_score(self):
        return json_path(self._extra_info, 'score', 'detail', 'maintenance')

    @classmethod
    def _request(cls, *path):
        if path and not (path[0].startswith('https://') or path[0].startswith('http://')):
            path = (cls.base_url,) + path

        for _ in range(3):
            try:
                r = requests.get("/".join(path), timeout=TIMEOUT)
            except requests.exceptions.Timeout:
                continue
            r.raise_for_status()
            return r
        raise IOError("Failed to reach %s. "
                      "Check your Internet connection." % cls.base_url)

    def releases(self, include_unstable=False, include_backports=False):
        """ Return package release labels

        Args:
            include_unstable (bool): whether to include releases including
                symbols other than dots and numbers.
            include_backports (bool): whether to include releases smaller in
                version than last stable release

        Returns:
             List[Tuple[str, str]]: (label, date), sorted by date
        """
        raise NotImplementedError

    def download_url(self, ver):
        """Get URL to package file of the specified version
        This function takes into account supported file types and their
        relative preference (e.g. wheel files before source packages)

        Args:
            ver (str): version string

        Returns:
            Optional[str]: url string if found, None otherwise
        """
        assert ver in self.info['releases']
        raise NotImplementedError

    def download(self, ver=None):
        """Download and extract the specified package version

        Args:
             ver (str): Version of the package

        Returns:
            Optional[str]: path to the folder with extracted package,
                None if download failed
        """
        raise NotImplementedError

    @d.cached_property
    def repository(self):
        """ Search for software repository URL

        Returns:
            Optional[str]: path to the folder with extracted package,
                None if download failed
        """
        raise NotImplementedError

    def dependencies(self, ver=None):
        """ Get technical dependencies

        Args:
            ver (Optional[str]): version string, latest version by default

        Returns:
            Dict[str, str]: dictionary of the form `{package: version}`;
                `version` might contain platform-specific modifiers, e.g.
                '>=3.12.1'. If not specified, `version will be `None`.
        """
        raise NotImplementedError

    def loc_size(self, ver):
        """ Get package size in LOC """
        raise NotImplementedError


import os, sys

class Cache(object):
    def __init__(self, arglist):
        self.number = arglist[0]
        self.latency = arglist[1]

    def __str__(self):
        return self.number + " " + self.latency

class Endpoint(object):
    def __init__(self, arglist):
        self.latency = arglist[0]
        self.count = arglist[1]
        self.caches = [Cache(i) for i in arglist[2]]

file = open("in.in", "r")
video = file.readline()
endpoint = file.readline()
request = file.readline()
caches = file.readline()
size = file.readline()
videos = file.readline().split()
endpoints = []
print(endpoint)
for i in range(int(endpoint)):
    endpoints.append(file.readline().split())
    count = endpoints[i][1]
    endpoints[i].append([file.readline().split() for j in range(int(count))])

print(endpoints)
endpoints_class = Endpoint(endpoints[0])

print([i.__str__() for i in endpoints_class.caches])


def create_index(self, fields, no_term_offsets=False,
                     no_field_flags=False, stopwords = None):
        """
        Create the search index. The index must not already exist.

        ### Parameters:

        - **fields**: a list of TextField or NumericField objects
        - **no_term_offsets**: If true, we will not save term offsets in the index
        - **no_field_flags**: If true, we will not save field flags that allow searching in specific fields
        - **stopwords**: If not None, we create the index with this custom stopword list. The list can be empty
        """

        args = [self.CREATE_CMD, self.index_name]
        if no_term_offsets:
            args.append(self.NOOFFSETS)
        if no_field_flags:
            args.append(self.NOFIELDS)
        if stopwords is not None and isinstance(stopwords, (list, tuple, set)):
            args += [self.STOPWORDS, len(stopwords)]
            if len(stopwords) > 0:
                args += list(stopwords)

        args.append('SCHEMA')

        args += list(itertools.chain(*(f.redis_args() for f in fields)))

        return self.redis.execute_command(*args)


# package com.gwittit.client.example

import java
from java import *
from java.util.List import List
from com.google.gwt.event.dom.client.ClickEvent import ClickEvent
from com.google.gwt.event.dom.client.ClickHandler import ClickHandler
from pyjamas import Window
from pyjamas.rpc import AsyncCallback
from pyjamas.ui import Anchor
from pyjamas.ui import HTML
from pyjamas.ui import VerticalPanel
from pyjamas.ui import Widget
from gwittit.client.facebook.entities import Notification

class Notifications_getList(Showcase):

    """
    Showcase for method calls notifications.getList and notifications.markRead

    @author olamar72
    """

    @java.init
    def __init__(self, *a, **kw):
        pass

    @__init__.register
    @java.typed()
    def __init__(self, ):
        self.__init__._super()
        outer = VerticalPanel()
        self.addLoader(outer)
        class _anonymous(AsyncCallback):

            @java.typed(Throwable)
            def onFailure(self, caught):
                self.handleFailure(caught)

            @java.typed(List)
            def onSuccess(self, result):
                self.removeLoader(outer)
                outer.add(HTML(u"Result Size " + java.str(result.size())))
                for no in result:
                    tmp = VerticalPanel()
                    tmp.addStyleName(u"notification")
                    tmp.add(HTML(java.str(u"
" + java.str(no.getTitleText())) + u"
"))
                    tmp.add(HTML(no.getBodyHtml()))
                    tmp.add(HTML(no.getHref()))
                    if not no.getIsUnread():
                        tmp.add(HTML(u"Status : Old"))
                    markRead = Anchor(u"Mark as Read")
                    class _anonymous(ClickHandler):

                        @java.typed(ClickEvent)
                        def onClick(self, event):
                            markRead.setHTML(u"Marked as Read")
                            markRead(no.getNotificationId())
                    markRead.addClickHandler(_anonymous())
                    tmp.add(markRead)
                    outer.add(tmp)
        self.apiClient.notificationsGetList(None, None, _anonymous()) #  Get facebook data
        self.initWidget(outer)

    @java.private
    @java.typed(Long)
    def markRead(self, nid):
        """
        * Mark notification as read.
        """
        class _anonymous(AsyncCallback):

            @java.typed(Throwable)
            def onFailure(self, caught):
                self.handleFailure(caught)

            @java.typed(Boolean)
            def onSuccess(self, result):
                if not result:
                    Window.alert(u"Failed to mark notification ")
        self.apiClient.notificationsMarkRead(nid, _anonymous()) #  Mark notification as read.


import os
import pickle
import numpy as np
import torch
import torch.nn as nn
import torch.autograd as autograd
from datetime import datetime

def get_constraint(bits, obj):
    if bits == 0:
        return None
    if 'activation' in obj:
        lower = 0
        upper = 2 ** bits
    else:
        lower = -2 ** (bits - 1) + 1
        upper = 2 ** (bits - 1)
    constraint = np.arange(lower, upper)
    return constraint

def train_one_epoch(net, train_loader, optimizer, criterion, log_fun=None):
    print('\n ... Training Model For One Epoch ...')
    net.train()
    msg_print = MessagePrinter(len(train_loader), freq=10)
    for index, (inputs, targets) in enumerate(train_loader):
        optimizer.zero_grad()
        inputs, targets = inputs.cuda(), targets.long().cuda()
        outputs = net(inputs)
        loss_classify = criterion(outputs, targets)
        loss_classify.backward()
        optimizer.step()
        # print msg and write log
        msg = msg_print(loss_classify, targets, outputs)
        if log_fun is not None:
            log_fun(index, net, msg)
    return msg_print.get_performance()

@autograd.no_grad()
def eval_performance(net, test_loader, criterion, log_fun=None):
    print('\n ... Evaluate Model Performance ...')
    net.eval()
    msg_print = MessagePrinter(len(test_loader), freq=10)
    for index, (inputs, targets) in enumerate(test_loader):
        inputs, targets = inputs.cuda(), targets.long().cuda()
        outputs = net(inputs)
        loss_classify = criterion(outputs, targets)
        msg = msg_print(loss_classify, targets, outputs)
        if log_fun is not None:
            log_fun(index, net, msg)
    return msg_print.get_performance()

class MessagePrinter:
    def __init__(self, total_iter, freq=10):
        self.iter_total = total_iter
        self.iter_curr = 0
        self.loss_cls = 0
        self.num_total = 0
        self.num_top1_correct = 0
        self.num_top5_correct = 0
        self.freq = freq

    def get_performance(self):
        loss_cls = round(self.loss_cls, 4)
        top1_acc = round(100. * self.num_top1_correct / self.num_total, 4)
        top5_acc = round(100. * self.num_top5_correct / self.num_total, 4)
        return [loss_cls, top1_acc, top5_acc]

    def __call__(self, loss_cls, targets, outputs):
        loss_cls = loss_cls.item()
        self.loss_cls = (self.loss_cls * self.iter_curr + loss_cls) / (self.iter_curr + 1)
        self.iter_curr += 1

        top1_correct, top5_correct = self.top1_top5_correct(targets, outputs)
        self.num_total += targets.shape[0]
        self.num_top1_correct += top1_correct
        self.num_top5_correct += top5_correct

        time_stamp = str(datetime.now())[:19]
        msg = '{}, {}/{}, Cls={:.3f}, Top1={:.3f}, Top5={:.3f}'
        top1_acc = 100. * self.num_top1_correct / self.num_total
        top5_acc = 100. * self.num_top5_correct / self.num_total
        show_msg = msg.format(time_stamp,
                              self.iter_curr,
                              self.iter_total,
                              self.loss_cls,
                              top1_acc,
                              top5_acc)
        if self.iter_curr % self.freq == 0 or self.iter_curr == self.iter_total:
            print(show_msg)
        return show_msg

    @staticmethod
    @autograd.no_grad()
    def top1_top5_correct(target, output, topk=(1, 5)):
        maxk = max(topk)
        _, pred = output.topk(k=maxk, dim=1, largest=True, sorted=True)
        pred = pred.t()
        correct = pred.eq(target.view(1, -1).expand_as(pred))
        res = []
        for k in topk:
            correct_k = correct[:k].view(-1).sum().item()
            res.append(correct_k)
        return res

class Trainer:
    def __init__(self, net, train_loader, test_loader, optimizer, lr_scheduler, model_name, train_loger=None):
        self.net = net
        self.train_loader = train_loader
        self.test_loader = test_loader
        self.optimizer = optimizer
        self.lr_scheduler = lr_scheduler
        self.model_name = model_name
        self.train_loger = train_loger
        self.criterion = nn.CrossEntropyLoss()

    def save_model(self):
        print('\n ... Save Model ...')
        model_path = os.path.join(self.train_loger.model_cache, self.model_name + '.pth')
        try:
            state_dict = self.net.module.state_dict()
        except AttributeError:
            state_dict = self.net.state_dict()
        torch.save(state_dict, model_path)

    def load_check_point(self):
        ckpt_cache = self.train_loger.ckpt_cache
        net_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_net.pth')
        opt_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_opt.pth')
        lrs_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_lrs.pth')
        self.net.load_state_dict(torch.load(net_path))
        self.optimizer.load_state_dict(torch.load(opt_path))
        self.lr_scheduler.load_state_dict(torch.load(lrs_path))

        epoch_acc_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_epoch_acc.pkl')
        with open(epoch_acc_path, 'rb') as fd:
            check_point = pickle.load(fd)
            start_epoch = check_point['start_epoch']
            best_quan_acc = check_point['best_quan_acc']
        return start_epoch, best_quan_acc

    def save_check_point(self, epoch, best_quan_acc):
        ckpt_cache = self.train_loger.ckpt_cache
        net_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_net.pth')
        opt_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_opt.pth')
        lrs_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_lrs.pth')
        torch.save(self.net.state_dict(), net_path)
        torch.save(self.optimizer.state_dict(), opt_path)
        torch.save(self.lr_scheduler.state_dict(), lrs_path)

        epoch_acc_path = os.path.join(ckpt_cache, self.model_name + '_ckpt_epoch_acc.pkl')
        with open(epoch_acc_path, 'wb') as fd:
            check_point = {'start_epoch': epoch + 1, 'best_quan_acc': best_quan_acc}
            pickle.dump(check_point, fd)

    def __call__(self, total_epoch, save_check_point=True, resume=False):
        start_epoch = 0
        best_quan_acc = 0
        if resume:
            start_epoch, best_quan_acc = self.load_check_point()
            print('\n Resume, start_epoch=%d, best_quan_acc=%.3f' % (start_epoch, best_quan_acc))

        for epoch in range(start_epoch, total_epoch):
            print("\n %s | Current: %d | Total: %d" % (datetime.now(), epoch + 1, total_epoch))
            train_perf_epoch = train_one_epoch(net=self.net,
                                               train_loader=self.train_loader,
                                               optimizer=self.optimizer,
                                               criterion=self.criterion,
                                               log_fun=self.train_loger.print_log)
            quan_perf_epoch = eval_performance(net=self.net,
                                               test_loader=self.test_loader,
                                               criterion=self.criterion,
                                               log_fun=self.train_loger.print_log)
            self.lr_scheduler.step()

            self.train_loger.print_perf(train_perf_epoch + quan_perf_epoch)
            if quan_perf_epoch[1] > best_quan_acc:
                best_quan_acc = quan_perf_epoch[1]
                self.save_model()

            if save_check_point:
                self.save_check_point(epoch, best_quan_acc)


class node:
    def __init__(self):
        self.val=None
        self.next=None
        self.prev=None

def printlist(head):
    while head!=None:
        print(head.val)
        head=head.next

def insertionSort(head):
    #sortowanie przez wstawianie
    #pierwszy posortowany
    if head==None or head.next==None:
        return head
    else:
        tmp=head.next
    while tmp!=None:
        temp=tmp
        while temp.prev!=None and temp.prev.val>temp.val:
            temp.prev.val,temp.val=temp.val,temp.prev.val
            temp=temp.prev
        tmp=tmp.next

head=node()
a=node()
b=node()
c=node()
d=node()
e=node()
head.val=6
a.val=9
b.val=4
c.val=5
d.val=1
e.val=3
head.next=a
a.next=b
b.next=c
c.next=d
d.next=e
e.next=None
head.prev=None
a.prev=head
b.prev=a
c.prev=b
d.prev=c
e.prev=d
printlist(head)
insertionSort(head)
print()
printlist(head)


import sys
import re

class StringCompression:
    """
    This is my solution to the exercise at https://techdevguide.withgoogle.com/paths/advanced/compress-decompression
    The goal of this exercise was to build a script that can decompress stings in the $number[$string] format, where
    $string is repeated $number times. The main caveat was that it is possible to stack multiple compressed strings into
    one another. (eg 2[xy23[z]y]x) This was solved using recursion.
    """

    regex = re.compile(r"([0-9]*)(\[)([a-z]+)(\])")
    """
    Matches all groups that are to be repeated
    """

    def do_decoding(self, sub_string):
        """
        Decompresses a string
        :param str sub_string:
        :return string:
        """
        for match in re.finditer(self.regex, sub_string):
            # iterate through all instances of repeated groups
            replace_string = match.group(3) * int(match.group(1))
            sub_string = sub_string.replace(match.group(0), replace_string)
            # replace the groups inside my string
        if re.search(self.regex, sub_string):
            # if the replacements caused new groups to be created, run this function over those as well
            sub_string = self.do_decoding(sub_string)
        return sub_string

compressor = StringCompression()
print(compressor.do_decoding(sys.argv[1]))


from OpenGL.GL import *
from OpenGL.GLU import *
import squaternion
import numpy as np
from operator import add
import glm

class Camera:
    def __init__(self, pos, zfar, znear, ratio, fovy=45, up=(0, 1, 0), look_at_pos=(0, 0, 0), rot_xy = (0,0), transform=(0,0,0)):
        self.pos = pos
        self.real_pos = pos
        # self.rot = rot
        self.zfar = zfar
        self.znear = znear
        self.ratio = ratio
        self.fovy = fovy
        self.up = up
        self.look_at_pos = look_at_pos
        self.rot_xy = rot_xy
        self.transform = transform
        self.view_matrix = None
        self.left_vector = np.array([1,0,0])
        self.up_vector = np.array([0,1,0])
        self.front_vector = np.array([0,0,1])
        self.relative_transform = np.array([0,0,0])

    def refresh_pos(self):
        if self.rot_xy:
            quat_rot = squaternion.euler2quat(self.rot_xy[1], self.rot_xy[0], 0, True)
            rot_angle = np.degrees(2 * np.arccos(quat_rot.w))
            square_coef = np.sqrt(1 - np.square(quat_rot.w))
            if rot_angle > 0.001 and square_coef > 0.001:
                rot_x = quat_rot.x / square_coef
                rot_y = quat_rot.y / square_coef
                rot_z = quat_rot.z / square_coef
                glRotatef(rot_angle, rot_x, rot_y, rot_z)
        glTranslatef(*[-coor for coor in self.transform])
        glTranslatef(*[-coor for coor in self.pos])

    def look_at(self):
        self.look_at_pos and gluLookAt(*tuple(np.array(self.pos) + np.array(self.transform)), *self.look_at_pos, *self.up_vector)

    def move_forward(self, amount):
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        self.view()
        glMatrixMode(GL_MODELVIEW)
        glPopMatrix()
        forward_normalized = self.front_vector / np.linalg.norm(self.front_vector)
        self.transform = tuple(np.array(self.transform) + (forward_normalized * amount))

    def move_left(self, amount):
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        self.view()
        glMatrixMode(GL_MODELVIEW)
        glPopMatrix()
        left_normalized = self.left_vector / np.linalg.norm(self.left_vector)
        self.transform = tuple(np.array(self.transform) + (left_normalized * amount))

    def view(self):
        self.look_at()
        self.refresh_pos()
        self.view_matrix = glGetDoublev(GL_MODELVIEW_MATRIX)
        self.left_vector = self.view_matrix[:3, 0]
        self.up_vector = self.view_matrix[:3, 1]
        self.front_vector = self.view_matrix[:3, 2]
        self.relative_transform = self.view_matrix[:3, 3]


######## TESTS ##########
import functions as ft

# variables to EX's
glob_paths_ex = ["./pdf/*/"]

def run_test():
    glob_paths_ex = ["./pdf/*/"]
    test_text = create_texts(list_xmls(glob_paths_ex))
    test_phrases = search_texts(test_text,{"artificial intelligence", "machine learning", " ml "," ai "},{"abstract","text"})
    test_clean = clean_text(test_phrases)
    (vect,vects) = create_n_gram(test_clean)
    model = run_lda(vects)
    return(vect,vects,model)

def print_model(model,vect):
    vocab = vect.get_feature_names()
    topic_word = model.topic_word_  # model.components_ also works
    n_top_words = 15
    for i, topic_dist in enumerate(topic_word):
        topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n_top_words+1):-1]
        print('Topic {}: {}'.format(i, ' '.join(topic_words)))

def get_topic_words(model,vect):
    vocab = vect.get_feature_names()
    topic_word = model.topic_word_  # model.components_ also works
    n_top_words = 15
    top_topic_words = []
    for i, topic_dist in enumerate(topic_word):
        topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n_top_words+1):-1]
        print('Topic {}: {}'.format(i, ' '.join(topic_words)))
        top_topic_words.append(topic_words)
    return(top_topic_words)

def phrases_json(model,vect):
    argamassa = [np.argmax(doc, axis=0) for doc in model.doc_topic_]
    test_phrases = search_texts(create_texts(list_xmls(["./pdf/*/"])),{"artificial intelligence", "machine learning", " ml "," ai "},{"abstract","text"})
    top_words = get_topic_words(model,vect)
    def addict(i,t):
        dicto = test_phrases[i]
        dicto["prob"] = model.doc_topic_[i,t]
        return(dicto)
    frases =[]
    for topic in range(model.doc_topic_[0].shape[0]):
        frases.append({"topic_id":topic,"top_words":list(top_words[topic]),"phrases":[addict(i,t) for i,t in enumerate(argamassa) if t == topic]})
    return(frases)

def test_final(out_file):
    (vect,vects,model) = run_test()
    topics_json = phrases_json(model,vect)
    if (out_file != None):
        with open('./'+out_file+'.json', 'w') as fout:
            json.dump(topics_json, fout)
    return(vect,vects,model)

#print (type(vects))
#print (len(vect.get_feature_names()))
#print(test_clean[0])
#print(vect.vocabulary_)
#print("")
#(vect,vects,model)=run_test()

#OLD CLEANING
    #regex = re.compile('[^a-zA-Z \-]')
    #string_without_punctuation = regex.sub('',phrase["phrase"])
    #string_without_punctuation = string_without_punctuation.replace('\r', '')
    #string_without_punctuation = string_without_punctuation.replace('\n', '')
    #text_tokens = word_tokenize(string_without_punctuation)
    #tokens_without_sw = [word for word in text_tokens if not word in stopwords.words()]
    #print(type(tokens_without_sw))


import os
import re
import glob
import pandas as pd
from io import StringIO

from django.conf import settings
from loguru import logger

description_split_text = 'DATA TRANSAKCJI:'

def extract_date_from_description(x):
    parts = re.split(description_split_text, x)
    if len(parts) > 1:
        return parts[1].strip()

    return None

def trim_description(x):
    parts = re.split(description_split_text, x)
    if len(parts) > 1:
        return parts[0].strip()

    return x

def trim_text_fields(x):
    return ' '.join(str(x).split())

def load_csv():
    # load all csv files from temp dir
    source_dir = os.path.join(settings.BASE_DIR, 'temp')
    field_names = ['Date', 'Added', 'Type', 'Description', 'Party Name', 'Party IBAN', 'Amount', 'Balance',
                   'Account Number']
    df = pd.DataFrame()

    list_of_files = glob.glob(os.path.join(source_dir, '*.csv'))
    for this_file in list_of_files:
        logger.info("adding {}".format(this_file))
        this_account_number = ''
        this_data = ''
        save_account_number = False
        save_transactions = False
        with open(this_file, encoding='cp1250') as f:
            for line in f:
                if line[:15] == '#Numer rachunku':
                    save_account_number = True
                elif line[:14][:9] == '#Data ksi':
                    save_transactions = True
                elif save_account_number:
                    this_account_number = line[:32].replace(' ', '')
                    save_account_number = False
                elif save_transactions:
                    if line[0] == '2':
                        this_data += line.replace("'", '"').replace('";"', "|;|").\
                            replace('";', "|;").replace(';"', ";|")
                    else:
                        save_transactions = False

        df_temp = pd.read_csv(StringIO(this_data), sep=';', comment='#', engine='python', names=field_names,
                              quotechar='|', encoding='cp1250', dtype={'Party IBAN': 'str'})

        logger.warning(this_file);
        logger.warning(this_data);
        logger.warning(this_account_number);
        # logger.info(df_temp);

        df_temp['Account Number'] = this_account_number
        df_temp['Source'] = os.path.basename(this_file)
        df_temp['Description'] = df_temp['Description'].fillna('')
        df_temp['Party IBAN'] = df_temp['Party IBAN'].fillna('')
        df_temp['Party Name'] = df_temp['Party Name'].fillna('')
        df_temp['Type'] = df_temp['Type'].fillna('')

        df_temp['Date Modified'] = df_temp['Description'].map(extract_date_from_description)
        df_temp['Description'] = df_temp['Description'].map(trim_text_fields)
        df_temp['Party Name'] = df_temp['Party Name'].map(trim_text_fields)
        df_temp['Type'] = df_temp['Type'].map(trim_text_fields)

        df_temp['Date Modified'] = df_temp['Date Modified'].fillna(df_temp['Date'])
        df_temp['Amount Modified'] = df_temp['Amount'].map(
            lambda x: float(re.sub('[^0-9\,\.-]','', x).replace(',', '.')))
        df_temp['Balance Modified'] = df_temp['Balance'].map(
            lambda x: float(re.sub('[^0-9\,\.-]', '', x).replace(',', '.')))

        df = df.append(df_temp, ignore_index=True)
        logger.info("added {}".format(df_temp.shape))

    logger.info("whole DF shape: {}".format(df.shape))
    logger.info(df.info())

    return df


from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
from pytest import mark

from controllers.cart_items_routes import router as cart_items_router
from controllers.cart_routes import router as cart_router
from controllers.product_routes import router as product_router
from controllers.user_routes import Request
from controllers.user_routes import router as user_router
from controllers.user_routes import status
from project_logs.logging import set_logging
from server.database import get_db
from server.database_test import drop_databases_to_test, get_db as get_test_db
from utils.generate_fakes import (
    generate_fake_cart,
    generate_fake_cart_item,
    generate_fake_products,
    generate_fake_user,
)

app = FastAPI()
app.include_router(user_router, tags=["user"], prefix="/user")
app.include_router(product_router, tags=["products"], prefix="/products")
app.include_router(cart_router, tags=["cart"], prefix="/cart")
app.include_router(cart_items_router, tags=["cart_item"], prefix="/cart/{cart_id}/item")

app.dependency_overrides[get_db] = get_test_db

@app.on_event("shutdown")
async def shutdown_db_client():
    await drop_databases_to_test()

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    project_errors = []
    project_error = {}
    error_log = set_logging("errors")
    for error in exc.errors():
        project_error["error_loc"] = error["loc"]
        project_error["error_type"] = error["type"]
        project_error["error_msg"] = error["msg"]
        project_errors.append(project_error)
        error_log.error(project_error)
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder(project_errors),
    )

@mark.asyncio
async def test_create_update_cart_item():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        quantity = 1
        response = await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], quantity
        )
        get_cart_response = client.get("/cart/" + user_id)
        assert response.status_code == 201
        body = response.json()
        assert body.get("cart").get("_id") == fake_cart.json().get("_id")
        assert body.get("cart").get("price") == 0
        assert body.get("product").get("price") == 9.99
        assert get_cart_response.json().get("price") == 9.99 * quantity

@mark.asyncio
async def test_create_update_cart_item_with_more_quantity():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        quantity = 20
        response = await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], quantity
        )
        get_cart_response = client.get("/cart/" + user_id)
        assert response.status_code == 201
        body = response.json()
        assert body.get("cart").get("_id") == fake_cart.json().get("_id")
        assert body.get("cart").get("price") == 0
        assert body.get("product").get("price") == 9.99
        assert get_cart_response.json().get("price") == 9.99 * quantity

@mark.asyncio
async def test_create_update_cart_item_missing_fields():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        quantity = 1
        await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], quantity
        )
        response = client.put(
            f"/cart/{body_client.json().get('_id')}/item/",
            json={
                "cart": fake_cart.json().get("_id"),
                "product": {
                    "description": "Doce gelado de morango",
                    "price": 9.99,
                },
            },
        )
        assert response.status_code == 422

@mark.asyncio
async def test_get_cart_item():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        first_product_id = fake_products.json()[0].get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        await generate_fake_cart_item(client, fake_cart.json(), fake_products.json()[0])
        get_cart_item_response = client.get(
            "/cart/" + fake_cart.json().get("_id") + "/item/" + first_product_id + "/"
        )
        assert get_cart_item_response.status_code == 200
        assert get_cart_item_response.json().get("cart") == fake_cart.json()
        assert get_cart_item_response.json().get("product") == fake_products.json()[0]

@mark.asyncio
async def test_get_cart_unexisting():
    with TestClient(app) as client:
        get_cart_response = client.get("/cart/unexisting_id")
        assert get_cart_response.status_code == 404

@mark.asyncio
async def test_delete_cart_item():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        first_product_id = fake_products.json()[0].get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        await generate_fake_cart_item(client, fake_cart.json(), fake_products.json()[0])
        delete_cart_item_response = client.delete(
            f"""/cart/{fake_cart.json().get("_id")}/item/{first_product_id}"""
        )
        assert delete_cart_item_response.status_code == 303

@mark.asyncio
async def test_delete_cart_item_with_more_quantity():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        first_product_id = fake_products.json()[0].get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], 4
        )
        delete_cart_item_response = client.delete(
            f"""/cart/{fake_cart.json().get("_id")}/item/{first_product_id}"""
        )
        assert delete_cart_item_response.status_code == 200

@mark.asyncio
async def test_delete_cart_item_unexisting():
    with TestClient(app) as client:
        delete_cart_response = client.delete("/cart/unexisting_id/item/10")
        assert delete_cart_response.status_code == 404

@mark.asyncio
async def test_delete_user_cascade():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], 4
        )
        delete_user_response = client.delete("/user/" + user_id)
        assert delete_user_response.status_code == 303
        get_user_response = client.get("/user/" + user_id)
        assert get_user_response.status_code == 404
        get_cart_response = client.get("/cart/" + user_id)
        assert get_cart_response.status_code == 404
        get_cart_item_response = client.get("/cart/" + fake_cart.json().get("_id"))
        assert get_cart_item_response.status_code == 404

@mark.asyncio
async def test_delete_cart_cascade():
    with TestClient(app) as client:
        body_client = await generate_fake_user(client)
        fake_products = await generate_fake_products(client)
        user_id = body_client.json().get("_id")
        fake_cart = await generate_fake_cart(client, user_id)
        await generate_fake_cart_item(
            client, fake_cart.json(), fake_products.json()[0], 4
        )
        delete_cart_response = client.delete("/cart/" + user_id)
        assert delete_cart_response.status_code == 200
        assert delete_cart_response.json().get("status") == "success"
        assert delete_cart_response.json().get("msg") == "Deleted the user cart"
        get_cart_response = client.get("/cart/" + user_id)
        assert get_cart_response.status_code == 404
        get_cart_item_response = client.get("/cart/" + fake_cart.json().get("_id"))
        assert get_cart_item_response.status_code == 404

if __name__ == "__main__":
    pass


"""
Cordy early / late LI analysis.
Compare target preference at the end of the day vs. the beginnig of the day for
days where only one set of targets was used (started on 11/22/2019)
"""
import nems.db as nd
import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from nems_lbhb.baphy_experiment import BAPHYExperiment

runclass = 'BVT'
animal = 'Cordyceps'
an_regex = "%"+animal+"%"
min_trials = 50
earliest_date = '2019_11_22'
window_length = 50 # how many trials in beginning / end to include

# get list of all training parmfiles
sql = "SELECT parmfile, resppath FROM gDataRaw WHERE runclass=%s and resppath like %s and training = 1 and bad=0 and trials>%s and behavior='active'"
parmfiles = nd.pd_query(sql, (runclass, an_regex, min_trials))

# screen for dates
parmfiles['date'] = [dt.datetime.strptime('-'.join(x.split('_')[1:-2]), '%Y-%m-%d') for x in parmfiles.parmfile]
ed = dt.datetime.strptime(earliest_date, '%Y_%m_%d')
parmfiles = parmfiles[parmfiles.date > ed]

results = pd.DataFrame(index=parmfiles['date'].unique(), columns=['Early', 'Late', 'Overall', 'nTrials'])
options = {}
for date in parmfiles['date'].unique():
    files = [p for i, p in parmfiles.iterrows() if p.date==date]
    files = [f['resppath']+f['parmfile'] for f in files]

    manager = BAPHYExperiment(files)
    events = manager.get_behavior_events(correction_method='baphy', **options)
    events = manager._stack_events(events)

    good_trials = events[(~events.invalidTrial)].Trial.unique()
    # note, number of target trials in performance dict doesn't have to add up to
    # number of window_length trials. There could (definitely are) FA trials
    # that are "valid trials", but not counted for behavior analysis bc target never
    # played

    params = manager.get_baphy_exptparams()[0]
    targets = np.array(params['TrialObject'][1]['TargetHandle'][1]['Names'])
    pump_dur = np.array(params['BehaveObject'][1]['PumpDuration'])
    r_tar = targets[pump_dur>0][0]
    nr_tar = targets[pump_dur==0][0]

    if len(good_trials) < (window_length * 1.5):
        all_trials = manager.get_behavior_performance(trials=None, **options)
        results.loc[date]['Overall'] = (all_trials['RR'][r_tar] - all_trials['RR'][nr_tar]) / \
                                    (all_trials['RR'][r_tar] + all_trials['RR'][nr_tar])
    else:
        all_trials = manager.get_behavior_performance(trials=None, **options)
        results.loc[date]['Overall'] = (all_trials['RR'][r_tar] - all_trials['RR'][nr_tar]) / \
                                            (all_trials['RR'][r_tar] + all_trials['RR'][nr_tar])
        results.loc[date]['nTrials'] = len(good_trials)

        # get LI for first 50 trials
        early_trials = good_trials[:window_length]
        early = manager.get_behavior_performance(trials=early_trials, **options)

        # get LI for last 50 trials
        late_trials = good_trials[-window_length:-10]
        late = manager.get_behavior_performance(trials=late_trials, **options)

        results.loc[date]['Early'] = (early['RR'][r_tar] - early['RR'][nr_tar]) / (early['RR'][r_tar] + early['RR'][nr_tar])
        results.loc[date]['Late'] = (late['RR'][r_tar] - late['RR'][nr_tar]) / (late['RR'][r_tar] + late['RR'][nr_tar])

# compare early / late learning index and show overall distribution of LI
f, ax = plt.subplots(1, 2, figsize=(8, 4))

ax[0].bar([0, 1], [results['Early'].mean(), results['Late'].mean()],
                yerr=[results['Early'].sem(), results['Late'].sem()],
                color='lightgrey', edgecolor='k')
ax[0].set_ylabel('Learning Index')
ax[0].set_xticks([0, 1])
ax[0].set_xticklabels(['Early', 'Late'])

bins = np.arange(-.5, .5, 0.05)
results['Overall'].plot.hist(edgecolor='white', bins=bins, ax=ax[1])
ax[1].set_xlabel('Learning Index')
ax[1].set_title('All Valid Trials')

f.tight_layout()

plt.show()


from django.urls import path
from rest_framework import routers
from rest_framework_simplejwt.views import TokenRefreshView

from .api import AuthViewSet, ListUsersViewSet, GetUserView
from .views import *

urlpatterns = [
    path("login/", login, name="login"),
    path("logout/", logout, name="logout"),
    path("register/", register, name="register"),
    path("settings/", settings, name="settings"),
    path("settings/tg_unlick", tg_unlink, name="tg_unlick"),
    path("", user_list, name="users"),
    path("profile/<str:username>/", profile, name="profile"),
    path("api/refresh", TokenRefreshView.as_view(), name="token_refresh"),
    path("api/list", ListUsersViewSet.as_view(), name="user_list"),
    path("api/list/<int:id>", GetUserView.as_view({"get": "list"}), name="user_api_id"),
]

router = routers.DefaultRouter(trailing_slash=False)
router.register("api", AuthViewSet, basename="api_auth")

urlpatterns += router.urls


"""
`{{cookiecutter.import_name}} help` will show detailed help information.
"""

import argparse

DESCRIPTION = __doc__

def build_arg_parser(argparser=None):
    if argparser is None:
        argparser = argparse.ArgumentParser()

    argparser.description = DESCRIPTION
    argparser.formatter_class = argparse.RawTextHelpFormatter

    argparser.add_argument(
        'argument_name',
        type=str,
        help='Get help on this.',
    )

    return argparser

def main(argument_name):
    print(f"This should show help for {argument_name!r}.")

{{ cookiecutter.folder_name }}/{{ cookiecutter.import_name }}/bin/help.py


# 299. 猜数字游戏

class Solution:
    def getHint(self, secret: str, guess: str) -> str:
        book = {}
        n = len(secret)

        a, b = 0, 0
        for i in range(n):
            if secret[i] == guess[i]:
                a += 1
            else:
                book[secret[i]] = book.get(secret[i], 0) + 1
        for i in range(n):
            if secret[i] != guess[i] and book.get(guess[i], 0) > 0:
                book[guess[i]] -= 1
                b += 1

        return str(a) + 'A' + str(b) + 'B'

s = Solution()
print(s.getHint(secret = "1", guess = "0"))


import sqlite3
from model.student_model import Student

# A class that provides configuration to setup and manipulate DB of the final project
class DBUtil:
    __DB_NAME = 'finalProject.db'
    __DROP_IF_EXISTS_STUDENTS = '''DROP Table IF EXISTS Students'''
    __CREATE_TABLE_STUDENTS = '''CREATE TABLE Students(
                                    registration INTEGER NOT NULL PRIMARY KEY,
                                    name TEXT NOT NULL,
                                    email TEXT NOT NULL,
                                    dBirth TEXT NOT NULL,
                                    hometown TEXT NOT NULL,
                                    score REAL NOT NULL)
                                '''
    __INSERT_STUDENT_QUERY = '''INSERT OR IGNORE INTO Students
                                    (registration, name, email, dBirth, hometown, score)
                                    VALUES(?, ?, ?, date(?), ?, ?)
                                '''
    __DELETE_STUDENT_QUERY = '''DELETE FROM Students
                                WHERE registration = ?
                                '''
    __GET_STUDENT_BY_ID_QUERY = '''SELECT * FROM Students
                                WHERE registration = ? ORDER BY registration
                            '''
    __GET_ALL_STUDENTS_QUERY = '''SELECT * FROM Students ORDER BY registration
                                '''
    __GET_ALL_STUDENTS_PAGING_QUERY = '''SELECT * FROM Students ORDER BY registration
                                            LIMIT ? OFFSET ?
                                        '''
    __GET_STUDENTS_PAGING_QUERY = '''SELECT DISTINCT * FROM Students
                                            WHERE registration = ? OR
                                                  name like ? OR
                                                  email like ? OR
                                                  dBirth = ? OR
                                                  hometown like ? OR
                                                  score = ?
                                            ORDER BY score, name DESC
                                            LIMIT ? OFFSET ?
                                            '''
    __UPDATE_STUDENT_QUERY = '''UPDATE Students
                                    SET registration = ?, name = ?, email = ?, dBirth = ?, hometown = ?, score = ?
                                    WHERE registration = ?
                                '''

    def __get_connection(self):
        return sqlite3.connect(self.__DB_NAME)

    def create_table_students(self):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__DROP_IF_EXISTS_STUDENTS)
        cur.execute(self.__CREATE_TABLE_STUDENTS)
        cur.close()
        db.commit()
        db.close()

    def insert_student(self, student: Student):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__INSERT_STUDENT_QUERY,
                    (student.registration,
                     student.name,
                     student.email,
                     student.dBirth,
                     student.hometown,
                     student.score,))
        cur.close()
        db.commit()
        db.close()

    def update_student(self, id,  student: Student):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__UPDATE_STUDENT_QUERY,
                    (student.registration,
                     student.name,
                     student.email,
                     student.dBirth,
                     student.hometown,
                     student.score,
                     id))
        cur.close()
        db.commit()
        db.close()

    def delete_student_by_registration(self, registration: int):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__DELETE_STUDENT_QUERY,
                    (registration,))
        self.__db_commit_and_close(db)

    def get_students_by_registration(self, registration: int):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__GET_STUDENT_BY_ID_QUERY,
                    (registration,))
        return cur.fetchone()

    def get_all_students(self):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__GET_ALL_STUDENTS_QUERY)
        return cur.fetchall()

    def get_all_students_by_pagination(self, limit=1, offset=0):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__GET_ALL_STUDENTS_PAGING_QUERY, (limit, offset))
        return cur.fetchall()

    def get_students_by_pagination(self, criteria, num, limit=1, offset=0):
        db = self.__get_connection()
        cur = db.cursor()
        cur.execute(self.__GET_STUDENTS_PAGING_QUERY, (num,
                                                       criteria,
                                                       criteria,
                                                       criteria,
                                                       criteria,
                                                       num,
                                                       limit,
                                                       offset))
        return cur.fetchall()

    def __db_commit_and_close(self, db):
        cur = db.cursor()
        db.commit()
        db.close()


import configparser
import random
import time

from common.util.html import get_html
from source.data import Data

def lj_spider(config, data):
    # 获取地址
    lj_area = config.get('website', 'lj_area')
    url = config.get('website', 'lj')

    for area in lj_area.split(','):
        # 区域Url格式化
        req_url = config.get('website', 'req_lj').format(area)
        # 爬取数据
        html = get_html(req_url)
        # 保存数据，获取最大页码
        max_page = data.lj_save(html, url, req_url, True)

        # 大于1页，遍历爬取
        for i in range(max_page + 1):
            if i > 1:
                req_url_pg = config.get('website', 'req_lj_pg').format(area, str(i))
                html = get_html(req_url_pg)
                data.lj_save(html, url, req_url, False)

        # 暂停时间，模拟人工操作
        time.sleep(random.randint(1, 10))

def bk_spider(config, data):
    bk_area = config.get('website', 'bk_area')
    url = config.get('website', 'bk')

    for area in bk_area.split(','):
        req_url = config.get('website', 'req_bk').format(area)
        html = get_html(req_url)
        max_page = data.bk_save(html, url, req_url, True)

        for i in range(max_page + 1):
            if i > 1:
                req_url_pg = config.get('website', 'req_bk_pg').format(area, str(i))
                html = get_html(req_url_pg)
                data.bk_save(html, url, req_url, False)

        time.sleep(random.randint(1, 10))

if __name__ == '__main__':
    print('Spider-Man!!')

    # 获取配置
    config = configparser.ConfigParser()
    config.read("config.ini")

    # 获取数据源
    data = Data(config)

    # lj_spider(config, data)
    bk_spider(config, data)


import numpy as np
from WeightedTree_opt import WeightedTree

class AdaBst_Alt:

    def __init__(self, X, Y, tmax):
        self.tmax = tmax
        self.X = X
        self.Y = Y
        self.n = X.shape[0]
        self.smp_w = np.zeros(shape=(tmax, self.n))
        self.st = np.zeros(shape=tmax, dtype=object)
        self.st_w = np.zeros(shape=tmax)
        self.err = np.zeros(shape=tmax)

    def adaclassifier(self):

        self.smp_w[0] = np.ones(shape=self.n) / self.n

        for t in range(self.tmax):
            # print("This is self.X")
            # print(self.X)
            # print(t)
            # 1) initialize distribution based on 1/n if it is first iteration
            # or on error weighted predictions of last iteration of not first
            curr_smp_w = self.smp_w[t]
            # 2) find and train weak learner
            weights = np.zeros(2)
            counter = 0
            # print("This is the official array")
            # print(self.smp_w[t])
            for i in self.Y:
                # print(self.smp_w[t][counter])
                if (i == 1):
                    weights[0] += self.smp_w[t][counter]
                    # print(weights)
                else:
                    weights[1] += self.smp_w[t][counter]
                    # print(weights)
                counter += 1

            # print("This is weights")
            # print(weights)

            stump = WeightedTree(None, 1, None, None, 0)
            stump = WeightedTree.make_tree(stump, self.X, self.Y, 0, 0, curr_smp_w)

            # print("This is dec bound")
            # print(stump.boundary)

            # 3) find predictions and error
            Ypred = WeightedTree.evaluate_data(tree=stump, data=self.X)
            # print(curr_smp_w)
            errcurr = curr_smp_w[(Ypred != self.Y)]
            errcurr = sum(errcurr)
            if(errcurr == 0):
                alphat = 1
            else:
                alphat = 0.5 * np.log((1 - errcurr) / errcurr)

            # calculating and renormalizing weight distribution for current stump for later visualization
            new_smp_w = (
                    curr_smp_w * np.exp(-alphat * self.Y * Ypred)
            )
            new_smp_w /= new_smp_w.sum()
            if t + 1 < self.tmax:
                self.smp_w[t + 1] = new_smp_w
            # print("weight after")
            # if t + 1 < self.tmax:
                # print(self.smp_w[t + 1])

            # store parameters of weak learners to be used in the aggregate decision making
            self.st[t] = stump
            self.st_w[t] = alphat
            self.err[t] = errcurr

        return self

    def predict(self, X):
        wlpreds = np.array([WeightedTree.evaluate_data(tree=stump, data=X) for stump in self.st])
        pred = np.sign(np.dot(self.st_w, wlpreds))
        # print(pred)
        # print(self.Y)
        return pred


from pwn import *

elf = ELF("./vuln")
ld = ELF("./lib/ld-linux-aarch64.so.1")
libc = ELF("./lib/libc.so.6")

context.binary = elf

target = process([ld.path, elf.path], env={"LD_PRELOAD": libc.path})
#target = remote("addr", 1337)

context.log_level = "DEBUG"

target.send("A"*16)

#gdb.attach(target, 'vm')

target.interactive()


""" Rules and Macros to allow running kubebuilder from within bazel.
"""

def _kubebuilder_impl(ctx):
    """Implementation of the _kubebuilder rule.

    Args:
      ctx: the repository_context
    """

    out_file = ctx.actions.declare_file(ctx.label.name + ".bash")
    substitutions = {
        "@@KUBEBUILDER_SHORT_PATH@@": ctx.executable._kubebuilder.short_path,
    }
    ctx.actions.expand_template(
        template = ctx.file._runner,
        output = out_file,
        substitutions = substitutions,
        is_executable = True,
    )
    runfiles = ctx.runfiles(files = [ctx.executable._kubebuilder])
    return [DefaultInfo(
        files = depset([out_file]),
        runfiles = runfiles,
        executable = out_file,
    )]

_kubebuilder = rule(
    implementation = _kubebuilder_impl,
    attrs = {
        "_kubebuilder": attr.label(
            default = "@kubebuilder_sdk//:bin/kubebuilder",
            allow_single_file = True,
            cfg = "host",
            executable = True,
        ),
        "_runner": attr.label(
            default = "@rules_kubebuilder//kubebuilder:kubebuilder-runner.sh.template",
            allow_single_file = True,
        ),
    },
    executable = True,
)

def kubebuilder(**kwargs):
    """ Macro to allow running kubebuilder from within Bazel.

    Args:
      **kwargs: the arguments to the macro.
    """
    tags = kwargs.get("tags", [])
    if "manual" not in tags:
        tags.append("manual")
        kwargs["tags"] = tags
    _kubebuilder(**kwargs)


import sys

banks = open(sys.argv[1], 'r').readline().strip().split("\t")
banks = list(map(lambda x: int(x), banks))

configurations = set()
cycles = 0

def redistibute():
    global banks
    global configurations
    global cycles

    index_of_max = banks.index(max(banks))

    buf = banks[index_of_max]
    banks[index_of_max] = 0

    curr_index = (index_of_max + 1) % len(banks)
    while (buf > 0):
        banks[curr_index] += 1
        buf -= 1
        curr_index = ((curr_index + 1) % len(banks))

while (True):
    if (str(banks) in configurations):
        break
    else:
        configurations.add(str(banks))
        redistibute()
        cycles += 1
print(str(cycles))


from datetime import datetime, timedelta
import vim

start_time = None
end_time = None

VIMODORO_INTERVAL = 1 # minutes

def vimodoro():
    if _is_timer_running():
        _start_vimodoro()
    else:
        _stop_vimodoro()

def _is_timer_running():
    return start_time is None and end_time is None

def _start_vimodoro():
    global start_time, end_time
    start_time = datetime.now()
    end_time = start_time + timedelta(minutes=VIMODORO_INTERVAL)

def _stop_vimodoro():
    # Reset the times
    global start_time, end_time
    start_time = end_time = None

def get_time_remaining():
    if end_time is None:
        vim.command(f"let full_time = '00:00'")
        return

    current_time = datetime.now()

    if current_time > end_time:
        seconds = 0
    else:
        time_left = end_time - current_time
        seconds = time_left.seconds

    minutes_left = seconds // 60
    seconds_left = seconds % 60
    full_time = str(minutes_left) + ':' + str(seconds_left)
    vim.command(f"let full_time = '{full_time}'")


import logging
import polib
from openai import OpenAI

import logging
from translator.translate_service import TranslateService

from translator.logger import format_log

logging.basicConfig(level=logging.INFO, format="%(message)s")
logging.getLogger("httpx").setLevel(logging.WARNING)

if __name__ == "__main__":
    input_file = "/home/oskar/git/translator/futurecoder_English.po"
    output_file = "/home/oskar/git/translator/futurecoder_Polish.po"

    po = polib.pofile(input_file)
    client = OpenAI()
    total_entries = len(po)
    translate_service = TranslateService(client, total_entries)
    for index, entry in enumerate(po):
        logging.info(format_log(entry.msgstr, "INPUT"))
        translated = translate_service.translate(entry.msgstr, index)
        entry.msgstr = translated
        logging.info(format_log(entry.msgstr, "OUTPUT"))
        po.save(output_file)


from nltk.tokenize import word_tokenize
from collections import defaultdict
from tqdm import tqdm
import numpy as np
import torch
from torch.utils.data import (TensorDataset, DataLoader, RandomSampler,
                              SequentialSampler)
import torch.optim as optim
import random
import CNN_model

def load_text(path):
    """Load text data, lowercase text and save to a list."""

    with open(path, 'rb') as f:
        texts = []
        for line in f:
            texts.append(line.decode(errors='ignore').lower().strip())

    return texts

def tokenize(texts):
    """Tokenize texts, build vocabulary and find maximum sentence length.

    Args:
        texts (List[str]): List of text data

    Returns:
        tokenized_texts (List[List[str]]): List of list of tokens
        word2idx (Dict): Vocabulary built from the corpus
        max_len (int): Maximum sentence length
    """

    max_len = 0
    tokenized_texts = []
    word2idx = {}

    # Add <pad> and <unk> tokens to the vocabulary
    word2idx['<pad>'] = 0
    word2idx['<unk>'] = 1

    # Building our vocab from the corpus starting from index 2
    idx = 2
    for sent in texts:
        tokenized_sent = word_tokenize(sent)

        # Add `tokenized_sent` to `tokenized_texts`
        tokenized_texts.append(tokenized_sent)

        # Add new token to `word2idx`
        for token in tokenized_sent:
            if token not in word2idx:
                word2idx[token] = idx
                idx += 1

        # Update `max_len`
        max_len = max(max_len, len(tokenized_sent))

    return tokenized_texts, word2idx, max_len

def encode(tokenized_texts, word2idx, max_len):
    """Pad each sentence to the maximum sentence length and encode tokens to
    their index in the vocabulary.

    Returns:
        input_ids (np.array): Array of token indexes in the vocabulary with
            shape (N, max_len). It will the input of our CNN model.
    """

    input_ids = []
    for tokenized_sent in tokenized_texts:
        # Pad sentences to max_len
        tokenized_sent += ['<pad>'] * (max_len - len(tokenized_sent))

        # Encode tokens to input_ids
        input_id = [word2idx.get(token) for token in tokenized_sent]
        input_ids.append(input_id)

    return np.array(input_ids)

def load_pretrained_vectors(word2idx, fname):
    """Load pretrained vectors and create embedding layers.

    Args:
        word2idx (Dict): Vocabulary built from the corpus
        fname (str): Path to pretrained vector file

    Returns:
        embeddings (np.array): Embedding matrix with shape (N, d) where N is
            the size of word2idx and d is embedding dimension
    """

    print("Loading pretrained vectors...")
    fin = open(fname, 'r', encoding='utf-8', newline='\n', errors='ignore')
    n, d = map(int, fin.readline().split())

    # Initilize random embeddings
    embeddings = np.random.uniform(-0.25, 0.25, (len(word2idx), d))
    embeddings[word2idx['<pad>']] = np.zeros((d,))

    # Load pretrained vectors
    count = 0
    for line in tqdm(fin):
        tokens = line.rstrip().split(' ')
        word = tokens[0]
        if word in word2idx:
            count += 1
            embeddings[word2idx[word]] = np.array(tokens[1:], dtype=np.float32)

    print(f"There are {count} / {len(word2idx)} pretrained vectors found.")

    return embeddings

def data_loader(train_inputs, val_inputs, train_labels, val_labels,
                batch_size=50):
    """Convert train and validation sets to torch.Tensors and load them to
    DataLoader.
    """

    # Convert data type to torch.Tensor
    train_inputs, val_inputs, train_labels, val_labels =\
    tuple(torch.tensor(data) for data in
          [train_inputs, val_inputs, train_labels, val_labels])

    # Specify batch_size
    batch_size = 50

    # Create DataLoader for training data
    train_data = TensorDataset(train_inputs, train_labels)
    train_sampler = RandomSampler(train_data)
    train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=batch_size)

    # Create DataLoader for validation data
    val_data = TensorDataset(val_inputs, val_labels)
    val_sampler = SequentialSampler(val_data)
    val_dataloader = DataLoader(val_data, sampler=val_sampler, batch_size=batch_size)

    return train_dataloader, val_dataloader

def initilize_model(pretrained_embedding=None,
                    freeze_embedding=False,
                    vocab_size=None,
                    device=None,
                    embed_dim=300,
                    filter_sizes=[3, 4, 5],
                    num_filters=[100, 100, 100],
                    num_classes=2,
                    dropout=0.5,
                    learning_rate=0.01):
    """Instantiate a CNN model and an optimizer."""

    assert (len(filter_sizes) == len(num_filters)), "filter_sizes and \
    num_filters need to be of the same length."

    # Instantiate CNN model
    cnn_model = CNN_model.CNN_model(pretrained_embedding=pretrained_embedding,
                        freeze_embedding=freeze_embedding,
                        vocab_size=vocab_size,
                        embed_dim=embed_dim,
                        filter_sizes=filter_sizes,
                        num_filters=num_filters,
                        num_classes=2,
                        dropout=0.5)

    # Send model to `device` (GPU/CPU)
    cnn_model.to(device)

    # Instantiate Adadelta optimizer
    optimizer = optim.Adadelta(cnn_model.parameters(),
                               lr=learning_rate,
                               rho=0.95)

    return cnn_model, optimizer

def set_seed(seed_value=42):
    """Set seed for reproducibility."""

    random.seed(seed_value)
    np.random.seed(seed_value)
    torch.manual_seed(seed_value)
    torch.cuda.manual_seed_all(seed_value)


# -*- coding: utf-8 -*-
"""Propagating cumulative surface hopping trajectories"""

from __future__ import division

import numpy as np

from .trajectory_sh import TrajectorySH

from typing import Any, List, Dict
from .typing import ArrayLike

class TrajectoryCum(TrajectorySH):
    """
    Trajectory surface hopping using a cumulative approach rather than instantaneous

    Instead of using a random number generator at every time step to test for a hop,
    hops occur when the cumulative probability of a hop crosses a randomly determined
    threshold. Swarmed results should be identical to the traditional variety, but
    should be a bit easier to reproduce since far fewer random numbers are ever needed.
    """

    def __init__(self, *args: Any, **kwargs: Any):
        """Constructor (see TrajectorySH constructor)"""
        TrajectorySH.__init__(self, *args, **kwargs)

        self.prob_cum = np.longdouble(0.0)
        self.zeta = self.draw_new_zeta()

    def snapshot(self) -> Dict:
        """returns loggable data"""
        out = {
            "time": self.time,
            "position": self.position.tolist(),
            "momentum": (self.mass * self.velocity).tolist(),
            "potential": self.potential_energy().item(),
            "kinetic": self.kinetic_energy().item(),
            "energy": self.total_energy().item(),
            "density_matrix": self.rho.view(np.float64).tolist(),
            "active": int(self.state),
            "electronics": self.electronics.as_dict(),
            "hopping": float(self.hopping),
            "zeta": float(self.zeta),
            "prob_cum": float(self.prob_cum)
        }
        return out

    def hopper(self, gkndt: ArrayLike) -> List[Dict]:
        """given a set of probabilities, determines whether and where to hop

        :param probs: [nstates] numpy array of individual hopping probabilities
        :returns: dictioanry with { "target": int, "weight": float, "zeta": float, "prob": float }
        """
        self.hopping = np.sum(gkndt)

        accumulated = np.longdouble(self.prob_cum)
        gkdt = np.sum(gkndt)
        accumulated += (accumulated - 1.0) * np.expm1(-gkdt)
        if accumulated > self.zeta:  # then hop
            # where to hop
            hop_choice = gkndt / gkdt

            zeta = self.zeta
            target = self.random_state.choice(list(range(self.model.nstates())), p=hop_choice)

            # reset probabilities and random
            self.prob_cum = 0.0
            self.zeta = self.draw_new_zeta()

            return [{"target": target, "weight": 1.0, "zeta": zeta, "prob": accumulated}]

        self.prob_cum = accumulated
        return []