import pickle
from unittest import TestCase
from dirty_models.model_types import ListModel
from dirty_models.fields import StringField, ArrayField, ModelField, MultiTypeField
from dirty_models.fields import IntegerField
from dirty_models.models import BaseModel

class TestTypes(TestCase):

    def test_list_model(self):

        test_list = ListModel()
        test_list.append(7)

        self.assertEqual(test_list.__modified_data__, [7])
        self.assertEqual(test_list.__original_data__, [])
        test_list.append(6)
        test_list.insert(1, 3)
        self.assertEqual(test_list.__modified_data__, [7, 3, 6])

    def test_list_model_iteration(self):

        test_list = ListModel([2, 4, 5])
        for val in test_list:
            self.assertEqual(val, test_list.__modified_data__[test_list.index(val)])

    def test_list_remove_field(self):
        test_list = ListModel([2, 4, 5])
        test_list.append(7)
        test_list.remove(4)
        self.assertEqual(test_list.__modified_data__, [2, 5, 7])

    def test_list_field_conversion(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())

        self.assertEqual(test_list.__modified_data__, ["2", "3", "4", "6"])

    def test_extend_with_invalid_elements(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        test_list.extend([{}, 3.4])
        self.assertEqual(test_list.__modified_data__, ["2", "3", "4", "6", "3.4"])

    def test_set_initialised_list(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        test_list[2] = {}
        test_list[3] = "hi"
        test_list.append("hi")
        self.assertEqual(test_list.__modified_data__, ["2", "3", "4", "hi", "hi"])

    def test_index_exception(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        self.assertRaises(ValueError, test_list.index, 7)

    def test_index_exception_not_initialised(self):
        test_list = ListModel()
        self.assertRaises(ValueError, test_list.index, 0)

    def test_get_items(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        self.assertEqual(test_list[0], "2")

    def test_get_items_flattered_list(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        test_list.flat_data()
        self.assertEqual(test_list[0], "2")

    def test_delete_item(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        del test_list[0]
        test_list.flat_data()
        self.assertEqual(test_list[0], "3")

    def test_delete_item_flattered(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        test_list.flat_data()
        del test_list[0]
        self.assertEqual(test_list[0], "3")

    def test_iter_not_initialised_goes_ok(self):
        test_list = ListModel()
        iterations = 0
        for x in test_list:
            iterations += 1
        self.assertEqual(iterations, 0)

    def test_iter_flattered(self):
        initial_list = [2, 3, "4", 6]
        test_list = ListModel(initial_list, field_type=StringField())
        test_list.flat_data()
        for x in test_list:
            self.assertEquals(x, str(initial_list[test_list.index(x)]))

    def test_clear_all_list(self):
        test_list = ListModel([2, 3, "4", 6])

        test_list.flat_data()
        test_list.append(1)
        self.assertEqual(test_list.__modified_data__, [2, 3, "4", 6, 1])
        self.assertEqual(test_list.__original_data__, [2, 3, "4", 6])
        test_list.clear_all()
        self.assertEqual(test_list.__modified_data__, None)
        self.assertEqual(test_list.__original_data__, [])

    def test_clear_list(self):
        test_list = ListModel([2, 3, "4", 6])

        test_list.flat_data()
        test_list.append(1)
        self.assertEqual(test_list.__modified_data__, [2, 3, "4", 6, 1])
        self.assertEqual(test_list.__original_data__, [2, 3, "4", 6])
        test_list.clear()
        self.assertIsNone(test_list.__modified_data__)
        self.assertEqual(test_list.__original_data__, [2, 3, "4", 6])

    def test_export_data_after_clear_all(self):
        test_list = ListModel([2, 3, "4", 6])

        test_list.flat_data()
        test_list.append(1)
        self.assertEqual(test_list.__modified_data__, [2, 3, "4", 6, 1])
        self.assertEqual(test_list.__original_data__, [2, 3, "4", 6])
        test_list.clear_all()
        self.assertEqual(test_list.export_data(), [])

    def test_export_modified_data_after_clear_all(self):
        test_list = ListModel([2, 3, "4", 6])

        test_list.flat_data()
        test_list.append(1)
        self.assertEqual(test_list.__modified_data__, [2, 3, "4", 6, 1])
        self.assertEqual(test_list.__original_data__, [2, 3, "4", 6])
        test_list.clear_all()
        self.assertEqual(test_list.export_modified_data(), [])

    def test_pop_element(self):
        test_list = ListModel([2, 3, "4", 6], field_type=StringField())
        test_list.pop(1)
        self.assertEqual(test_list.__modified_data__, ["2", "4", "6"])
        test_list.flat_data()
        test_list.pop(1)
        self.assertEqual(test_list.__modified_data__, ["2", "6"])
        self.assertEqual(test_list.__original_data__, ["2", "4", "6"])

    def test_pop_unitialised(self):
        test_list = ListModel()
        self.assertRaises(IndexError, test_list.pop, 0)

    def test_count_elements(self):
        test_list = ListModel([2, 3, "4", 6])
        self.assertEqual(test_list.count(3), 1)
        test_list.pop(1)
        test_list.flat_data()
        self.assertEqual(test_list.count(3), 0)

    def test_count_unitialised(self):
        test_list = ListModel()
        self.assertEqual(test_list.count("whatever"), 0)

    def test_length_unitialised(self):
        test_list = ListModel()
        self.assertEqual(0, len(test_list))

    def test_reverse(self):
        test_list = ListModel(["one", "two", "three", []], field_type=StringField())
        test_list.reverse()
        self.assertEqual(["three", "two", "one"], list(test_list))

    def test_sort(self):
        test_list = ListModel(["one", "two", 1, 2, 9, 3, "three", []], field_type=IntegerField())
        test_list.sort()
        self.assertEqual([1, 2, 3, 9], list(test_list))

    def test_length_initialised(self):
        test_list = ListModel([2, 3, "4", 6])
        self.assertEqual(4, len(test_list))

    def test_length_initialised_flattered(self):
        test_list = ListModel([2, 3, "4", 6])
        test_list.flat_data()
        self.assertEqual(4, len(test_list))
        self.assertEqual(4, len(test_list))

    def test_import_data(self):
        test_list = ListModel()
        test_list.import_data(set([1, 2]))
        self.assertTrue(1 in test_list)

    def test_invalid_index(self):
        test_list = ListModel([2, 4, 5])

        with self.assertRaises(TypeError):
            test_list[23.12]

    def test_out_of_bounds_index(self):
        test_list = ListModel([2, 4, 5])

        with self.assertRaises(IndexError):
            test_list[23]

class ContainsItemTests(TestCase):

    def test_contains_item_original_data(self):

        list_model = ListModel([1])
        list_model.flat_data()

        self.assertTrue(1 in list_model)

    def test_contains_item_modified_data(self):
        list_model = ListModel([1])

        self.assertTrue(1 in list_model)

    def test_not_contains_item_original_data(self):
        list_model = ListModel([2])
        list_model.flat_data()

        self.assertFalse(1 in list_model)

    def test_not_contains_item_modified_data(self):
        list_model = ListModel([1, 2])
        list_model.flat_data()
        list_model.pop(0)
        self.assertFalse(1 in list_model)

class ExportDeletedFieldsTests(TestCase):

    class Model(BaseModel):
        test_int = IntegerField()
        test_array = ArrayField(field_type=MultiTypeField(field_types=[IntegerField(),
                                                                       ModelField()]))

    def test_inner_model_deleted_field(self):

        model = self.Model({'test_array': [{'test_int': 1},
                                           {'test_int': 2},
                                           3]})

        model.flat_data()

        del model.test_array[1].test_int
        self.assertEqual(model.export_deleted_fields(), ['test_array.1.test_int'])

class PicklableModel(BaseModel):
    int_field = IntegerField()

class PicklableListTests(TestCase):

    def _assert_equal_after_pickle(self, list_model):

        list_model_unpickled = pickle.loads(pickle.dumps(list_model))

        self.assertNotEqual(id(list_model),
                            id(list_model_unpickled))
        self.assertEqual(list_model_unpickled.__original_data__,
                         list_model.__original_data__)
        self.assertEqual(list_model_unpickled.__modified_data__,
                         list_model.__modified_data__)
        self.assertEqual(list_model_unpickled.get_field_type().__class__,
                         list_model.get_field_type().__class__)
        self.assertEqual(list_model_unpickled.get_field_type().export_definition(),
                         list_model.get_field_type().export_definition())

    def test_integer_field(self):
        list_model = ListModel([1, 2], field_type=IntegerField())
        list_model.flat_data()

        self._assert_equal_after_pickle(list_model)

    def test_integer_field_modified(self):
        list_model = ListModel([1, 2], field_type=IntegerField())
        list_model.flat_data()

        list_model.append(3)

        self._assert_equal_after_pickle(list_model)

    def test_string_field(self):
        list_model = ListModel(['aaaa', 'bbbb', 'cccc'], field_type=StringField())
        list_model.flat_data()

        list_model.pop()

        self._assert_equal_after_pickle(list_model)

    def test_model_field(self):

        list_model = ListModel([{'int_field': 1}, {'int_field': 2}, {'int_field': 3}],
                               field_type=ModelField(model_class=PicklableModel))
        list_model.flat_data()

        list_model.pop()

        list_model_unpickled = pickle.loads(pickle.dumps(list_model))

        self.assertNotEqual(id(list_model),
                            id(list_model_unpickled))
        self.assertEqual([i.export_data() for i in list_model_unpickled.__original_data__],
                         [i.export_data() for i in list_model.__original_data__])
        self.assertEqual([i.export_data() for i in list_model_unpickled.__modified_data__],
                         [i.export_data() for i in list_model.__modified_data__])
        self.assertEqual(list_model_unpickled.get_field_type().__class__,
                         list_model.get_field_type().__class__)
        self.assertEqual(list_model_unpickled.get_field_type().export_definition(),
                         list_model.get_field_type().export_definition())

        original_list = [i for i in list_model_unpickled.__original_data__]
        original_list.pop()

        self.assertEqual(original_list,
                         list_model_unpickled.__modified_data__)


# import encoder
import torchvision
import torch
import numpy as np
from numpy.testing import assert_array_almost_equal, assert_array_equal, assert_allclose
#import matplotlib.pyplot as plt

import sys
sys.path.append('../')
import os
sys.path.append(os.getcwd())

from encoder import rans, coder

precision = 24
#torch.manual_seed(42)

def test_encodeDecode():
    #encode/decoder a MNIST image using its own distribution

    batchSize = 10
    lambd = lambda x: (x * 255).byte()
    trainsetTransform = torchvision.transforms.Compose([
        torchvision.transforms.ToTensor(),
        torchvision.transforms.Lambda(lambd)
    ])
    trainSet = torchvision.datasets.MNIST(root='./data/mnist', train=True,
                                          download=True, transform=trainsetTransform)
    trainLoader = torch.utils.data.DataLoader(trainSet, batch_size=batchSize, shuffle=True)
    dataIter = iter(trainLoader)
    images, _ = dataIter.next()
    images = images.float()

    nBins = 510 # 255 * 2, only half is used, can be optimized

    HISTos = []
    MEANs = []
    theoryBPD = []
    CDFs = []

    for i in range(batchSize):
        mean = int(0.5 * (images[i]).max() + images[i].min())
        MEANs.append(mean)

        histogram = torch.histc(images[i] - mean, bins=nBins, min=-nBins // 2, max=nBins // 2)
        HISTos.append(histogram)

        prob = histogram / np.prod(images[i].shape)
        logp = -torch.log2(prob)
        logp[logp == float('inf')] = 0
        theorySize = (logp * histogram).sum().item()
        theoryBPD.append(theorySize / np.prod(images.shape[1:]))

        cdf = prob.numpy()
        for j in range(prob.shape[0] - 1):
            cdf[j + 1] = cdf[j] + cdf[j + 1]

        # np.arange(nBins)).reshape(1, nBins)) here to avoid zero freq in ans, add extra BPD
        CDFs.append(torch.from_numpy((cdf * ((1 << precision))).astype('int').reshape(1, nBins)))
                                     # + np.arange(nBins)).reshape(1, nBins))

    MEANs = torch.tensor(MEANs).reshape(batchSize, 1)
    CDFs = torch.cat(CDFs, 0).numpy()

    print("theory BPD:", np.mean(theoryBPD))
    tBPD = np.mean(theoryBPD)

    states = []
    # suppose all pixels have the same CDFs[0]
    CDFs = np.uint32(CDFs)
    for i in range(batchSize):
        # symbols is transformed to match the indices for the CDFs array
        symbols = images[i] - MEANs[i] + nBins // 2 - 1
        symbols = symbols.reshape(-1).int()
        state = rans.x_init
        for j in reversed(range(len(symbols))):
            state = coder.encoder(CDFs[i], symbols[j], state)
        state = rans.flatten(state)
        states.append(state)

    print("actual BPD:", np.mean([32 * len(term) / np.prod(images.shape[1:]) for term in states]))
    aBPD = np.mean([32 * len(term) / np.prod(images.shape[1:]) for term in states])

    assert_allclose(tBPD, aBPD, rtol=1e-1)

    reconstruction = [[] for i in range(batchSize)]
    for i in range(batchSize):
        symbols = images[i] - MEANs[i] + nBins // 2 - 1
        symbols = symbols.reshape(-1).int()
        state = rans.unflatten(states[i])
        for j in range(symbols.shape[0]):
            state, recon_symbol = coder.decoder(CDFs[i], state)
            reconstruction[i].append(recon_symbol + MEANs[i] - nBins // 2 + 1)

    reconstruction = torch.tensor(reconstruction)
    recon_images = torch.cat([reconstruction[i].reshape(images[i].shape) for i in range(batchSize)], dim=0)

    assert_array_equal(images.reshape(batchSize, 28, 28).detach().numpy(), recon_images.detach().numpy())

'''
def test_encodeDecode_otherDistr():
    #encode/decoder a MNIST image using OTHER distribution

    batchSize = 2
    lambd = lambda x: (x * 255).byte()
    trainsetTransform = torchvision.transforms.Compose([
        torchvision.transforms.ToTensor(),
        torchvision.transforms.Lambda(lambd)
    ])
    trainSet = torchvision.datasets.MNIST(root='./data/mnist', train=True,
                                          download=True, transform=trainsetTransform)
    trainLoader = torch.utils.data.DataLoader(trainSet, batch_size=batchSize, shuffle=True)
    dataIter = iter(trainLoader)
    images, _ = dataIter.next()

    histogram = torch.randint(1, 255, [256]).to(torch.float32)

    for i in range(len(histogram) - 1):
        histogram[i + 1] = histogram[i] + histogram[i + 1]

    CDF = [histogram[i] / histogram[len(histogram) - 1] for i in range(len(histogram))]
    states = [None for i in range(batchSize)]
    for i in range(batchSize):
        symbols = images[i].reshape(-1).numpy()
        for symbol in symbols[::-1]:
            states[i] = coder.encoder(CDF, symbol, states[i])

    reconstruction = [[] for i in range(batchSize)]
    for i in range(batchSize):
        symbols = images[i].reshape(-1)
        for symbol in symbols:
            states[i], recon_symbol = coder.decoder(CDF, states[i])
            if symbol != recon_symbol:
                raise ValueError
            else:
                reconstruction[i].append(recon_symbol)

    reconstruction = torch.tensor(reconstruction)
    recon_images = torch.cat([reconstruction[i].reshape(images[i].shape) for i in range(batchSize)], dim=0)

    assert_array_equal(images.reshape(batchSize, 28, 28).detach().numpy(), recon_images.detach().numpy())
'''

if __name__ == "__main__":
    test_encodeDecode()


import requests
import json
import config

class Notifications (object) :

    def matchTokens (self, devicesList, tokenDevices):
        tokens  = []
        for dev in devicesList :
            for token in tokenDevices:
                if(token["refDevice"] == dev["id"]):
                    tokens.append(token)
        return tokens

    def clearTokens(self, alertSource, near, onZone, allTokens):
        near = self.matchTokens(near, allTokens)
        onZone = self.matchTokens(onZone, allTokens)

        temp = {}
        print("DEVICES ON ZONE")
        for devNear in near :
            temp[devNear ["refDevice"]] = devNear["fcmToken"]
            print(devNear["refDevice"])

        print("DEVICES NEAR")
        for devZone in onZone :
            temp[devZone ["refDevice"]] = devZone["fcmToken"]
            print(devZone["refDevice"])

        array = []
        devices = []
        for device in temp :
            if (device != alertSource) :
                array.append(temp[device])
                devices.append(device)

        return array, devices

    def sendNotifications(self, alert , tokens, devices):
        color = ""
        if(alert["severity"] == "informational"):
            color = "#3498db"
        if(alert["severity"] == "low"):
            color = "#2c3e50"
        if(alert["severity"] == "medium"):
            color = "#f1c40f"
        if(alert["severity"] == "high"):
            color = "#e67e22"
        if(alert["severity"] == "critical"):
            color = "#c0392b"

        print (alert["severity"])
        body = {
            "notification": {
                "title": alert["category"],
                "body": alert["subCategory"],
                "color": color

            },
            "data": {
                "alert" : alert
            },
            "ttl": 3600
        }
        headers = {
            "Content-Type":"application/json",
            "Authorization":'key=' + config.fcm
        }
        print(tokens)
        index = 0
        for token in tokens :
            body["to"] = token
            res = requests.post("http://fcm.googleapis.com/fcm/send",data=json.dumps(body),headers=headers)
            print (res, devices[index])
            index += 1
        return


# encoding: utf-8
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Author: Kyle Lahnakoski (kyle@lahnakoski.com)
#
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import sys

from mo_dots import set_attr as mo_dots_set_attr
from mo_dots import wrap, join_field, split_field

DEBUG = True

def set(constants):
    """
    REACH INTO THE MODULES AND OBJECTS TO SET CONSTANTS.
    THINK OF THIS AS PRIMITIVE DEPENDENCY INJECTION FOR MODULES.
    USEFUL FOR SETTING DEBUG FLAGS.
    """
    if not constants:
        return
    constants = wrap(constants)

    for k, new_value in constants.leaves():
        errors = []
        try:
            old_value = mo_dots_set_attr(sys.modules, k, new_value)
            continue
        except Exception as e:
            errors.append(e)

        # ONE MODULE IS MISSING, THE CALLING MODULE
        try:
            caller_globals = sys._getframe(1).f_globals
            caller_file = caller_globals["__file__"]
            if not caller_file.endswith(".py"):
                raise Exception("do not know how to handle non-python caller")
            caller_module = caller_file[:-3].replace("/", ".")

            path = split_field(k)
            for i, p in enumerate(path):
                if i == 0:
                    continue
                prefix = join_field(path[:1])
                name = join_field(path[i:])
                if caller_module.endswith(prefix):
                    old_value = mo_dots_set_attr(caller_globals, name, new_value)
                    if DEBUG:
                        from mo_logs import Log

                        Log.note(
                            "Changed {{module}}[{{attribute}}] from {{old_value}} to {{new_value}}",
                            module=prefix,
                            attribute=name,
                            old_value=old_value,
                            new_value=new_value
                        )
                    break
        except Exception as e:
            errors.append(e)

        if errors:
            from mo_logs import Log

            Log.error("Can not set constant {{path}}", path=k, cause=errors)


import sys

from typing import Text, Tuple, List, Set, Dict, Type, Union, Callable
from collections import defaultdict
from copy import deepcopy
from random import randint
from threading import local

from appyratus.utils.dict_utils import DictObject

from ravel.util.loggers import console
from ravel.util.misc_functions import (
    get_class_name,
    flatten_sequence,
)
from ravel.util import (
    is_resource_type, is_batch_type,
    is_resource, is_batch,
)
from ravel.query.order_by import OrderBy
from ravel.query.request import Request
from ravel.query.predicate import (
    Predicate,
    ConditionalPredicate,
    BooleanPredicate,
    OP_CODE,
)

from .resolver_decorator import ResolverDecorator
from .resolver_property import ResolverProperty

class ResolverMeta(type):
    def __init__(cls, name, bases, dict_):
        cls.ravel = DictObject()
        cls.ravel.local = local()
        cls.ravel.local.is_bootstrapped = False

class Resolver(metaclass=ResolverMeta):

    app = None  # TODO: use cls.ravel.app instead

    def __init__(
        self,
        target=None,
        name=None,
        owner=None,
        decorator=None,
        on_resolve=None,
        on_resolve_batch=None,
        on_select=None,
        on_save=None,
        on_set=None,
        on_get=None,
        on_delete=None,
        on_dump=None,
        private=False,
        nullable=True,
        required=False,
        immutable=False,
        many=False,
    ):
        self.name = name
        self.owner = owner
        self.private = private
        self.nullable = nullable
        self.decorator = decorator
        self.required = required
        self.target_callback = None
        self.target = None
        self.schema = None
        self.many = many
        self.immutable = immutable

        self.on_resolve = on_resolve or self.on_resolve
        self.on_resolve_batch = on_resolve_batch or self.on_resolve_batch
        self.on_select = on_select or self.on_select
        self.on_save = on_save or self.on_save
        self.on_dump = on_dump or self.on_dump
        self.on_get = on_get or self.on_get
        self.on_set = on_set or self.on_set
        self.on_delete = on_delete or self.on_delete

        if is_resource_type(target):
            self.target = target
            self.many = False
        elif is_batch(target):
            self.target = target.owner
            self.many = True
        elif target is not None:
            assert callable(target)
            self.target_callback = target

    def __repr__(self):
        return (
            f'{get_class_name(self)}('
            f'target={get_class_name(self.owner)}.{self.name}'
            f')'
        )

    @classmethod
    def is_bootstrapped(cls):
        return getattr(cls.ravel.local, 'is_bootstrapped', False)

    @classmethod
    def property_type(cls):
        return ResolverProperty

    @classmethod
    def build_property(cls, decorator=None, args=None, kwargs=None):
        args = args or tuple()
        kwargs = kwargs or {}
        resolver = cls(*args, **kwargs)
        property_type = cls.property_type()
        return property_type(resolver, decorator=decorator)

    @classmethod
    def build_decorator(cls, *args, **kwargs):
        class decorator_type(ResolverDecorator):
            def __init__(self, *args, **kwargs):
                super().__init__(cls, *args, **kwargs)

        decorator_type.__name__ = f'{get_class_name(cls)}Decorator'
        return decorator_type

    @classmethod
    def priority(self) -> int:
        """
        Proprity defines the order in which Resolvers execute when executing a
        query, in ascending order.
        """
        return sys.maxsize

    @classmethod
    def tags(cls) -> Set[Text]:
        """
        In development, you can access all Resolvers by tag.  For example, if
        you had a User class with a Resolver called "account" whose class was
        tagged with "my_tag", then you could access this resolver in a
        tag-specific dictionary by doing this:

        ```py
        account_resolver = User.resolvers.my_tag['account']

        # equivalent to doing...
        account_resolver = User.account.resolver
        ```
        """
        return {'untagged'}

    @staticmethod
    def sort(resolvers: List['Resolver']) -> List['Resolver']:
        """
        Sort and return the input resolvers as a new list, orderd by priority
        int, ascending. This reflects the relative order of intended execution,
        from first to last.
        """
        return sorted(resolvers, key=lambda resolver: resolver.priority())

    def copy(self, new_owner: Type['Resource'] = None) -> 'Resolver':
        clone = type(self)(
            target=self.target,
            name=self.name,
            owner=new_owner or self.owner,
            decorator=self.decorator,
            on_resolve=self.on_resolve,
            on_resolve_batch=self.on_resolve_batch,
            on_select=self.on_select,
            on_save=self.on_save,
            on_set=self.on_set,
            on_get=self.on_get,
            on_delete=self.on_delete,
            on_dump=self.on_dump,
            private=self.private,
            nullable=self.nullable,
            required=self.required,
            immutable=self.immutable,
            many=self.many,
        )

        clone.target_callback = self.target_callback
        clone._is_bound = False

        self.on_copy(clone)

        return clone

    @classmethod
    def bootstrap(cls, app: 'Application'):
        console.debug(f'bootstrapping {get_class_name(cls)} class')
        cls.app = app
        cls.on_bootstrap()
        cls.ravel.local.is_bootstrapped = True

    def bind(self):
        if self.target_callback:
            self.app.inject(self.target_callback)
            target = self.target_callback()
            if is_resource_type(target):
                self.target = target
                self.many = False
            elif is_batch_type(target):
                self.target = target.ravel.owner
                self.many = True
            else:
                raise Exception('unrecognized target class')

        if not self.owner.ravel.is_abstract:
            self.on_bind()

        if self.target is not None:
            self.schema = self.target.Schema(name=self.name)

        self._is_bound = True

    def resolve(self, entity: 'Entity', request=None):
        if request is None:
            request = Request(self)

        if is_resource(entity):
            return self.resolve_resource(entity, request)
        else:
            assert is_batch(entity)
            return self.resolve_batch(entity, request)

    def resolve_resource(self, resource: 'Resource', request):
        self.pre_resolve(resource, request)

        if self.app.mode == 'normal':
            result = self.on_resolve(resource, request)
        elif self.app.mode == 'simulation':
            result = self.on_simulate(resource, request)

        processed_result = self.post_resolve(resource, request, result)
        request.result = processed_result
        return processed_result

    def resolve_batch(self, batch: 'Batch', request):
        self.pre_resolve_batch(batch, request)

        if self.app.mode == 'normal':
            result = self.on_resolve_batch(batch, request)
        elif self.app.mode == 'simulation':
            result = {res: self.on_simulate(res, request) for res in batch}

        processed_result = self.post_resolve_batch(batch, request, result)
        return processed_result

    def generate(self, instance=None, request=None):
        if instance is None:
            instance = self.owner.generate()

        if request is None:
            request = Request(self)

        self.pre_resolve(instance, request)
        result = self.on_simulate(instance, request)
        processed_result = self.post_resolve(instance, request, result)

        return processed_result

    def dump(self, dumper: 'Dumper', value):
        return value

    @classmethod
    def on_bootstrap(cls):
        pass

    def on_bind(self):
        return

    def on_copy(self, copy: 'Resolver'):
        pass

    def pre_resolve(self, resource, request):
        return

    def on_resolve(self, resource, request):
        raise NotImplementedError()

    def post_resolve(self, resource, request, result):
        return result

    def on_select(self, request):
        return

    def on_get(self, resource, value):
        return

    def on_set(self, resource, old_value, new_value):
        return

    def on_delete(self, resource, value):
        return

    def on_dump(self, request, value):
        pass

    def on_save(self, resource, value):
        pass

    def on_simulate(self, resource, request):
        query = request.resolver.target.select(request=request)
        if self.many:
            return query.execute(simulate=True)
        else:
            return query.execute(first=True, simulate=True)

    def pre_resolve_batch(self, batch, request):
        return

    def on_resolve_batch(self, batch, request):
        return None

    def post_resolve_batch(self, batch, request, result):
        return result


"""
Created on 11/20/2018

@author: RH
"""
# This simulator is created by using the ideas of Extended Data Figure 3.
import matplotlib
matplotlib.use('Agg')
import numpy as np
import cv2

Pr = 6  # Antibiotics radius of species P.
RDr = 3  # Removing antibiotics radius of species RD
r = 4  # Reproducing radius of all 3 species
sz = 200  # Size of simulation graph
Srepro = 1  # Number of offsprings produced by species S each round
RDrepro = 1  # Number of offsprings produced by species RD each round
Prepro = 1  # Number of offsprings produced by species P each round

# Initialize the graph with 'num' of species randomly placed
def init_placement(sz, num, x, Pr, RDr):
    mp = np.full((sz+1, sz+1, 3), 1)
    loc = []
    for i in range(num):
        rand = np.random.randint(sz, size=2)
        if x == 2:
            mp[rand[0], rand[1], x] = 255
            mp[rand[0], rand[1], 0] = 0
            mp[rand[0], rand[1], 1] = 0
        elif x == 1:
            mp[np.maximum((rand[0]-RDr), 0):np.minimum((rand[0] + RDr), sz),
            np.maximum((rand[1]-RDr), 0):np.minimum((rand[1] + RDr), sz), x] = 255

            mp[np.maximum((rand[0] - RDr), 0):np.minimum((rand[0] + RDr), sz),
            np.maximum((rand[1] - RDr), 0):np.minimum((rand[1] + RDr), sz), 0] = 0

            mp[np.maximum((rand[0] - RDr), 0):np.minimum((rand[0] + RDr), sz),
            np.maximum((rand[1] - RDr), 0):np.minimum((rand[1] + RDr), sz), 2] = 0
        elif x == 0:
            mp[np.maximum((rand[0] - Pr), 0):np.minimum((rand[0] + Pr), sz),
            np.maximum((rand[1] - Pr), 0):np.minimum((rand[1] + Pr), sz), x] = 255

            mp[np.maximum((rand[0] - Pr), 0):np.minimum((rand[0] + Pr), sz),
            np.maximum((rand[1] - Pr), 0):np.minimum((rand[1] + Pr), sz), 1] = 1

            mp[np.maximum((rand[0] - Pr), 0):np.minimum((rand[0] + Pr), sz),
            np.maximum((rand[1] - Pr), 0):np.minimum((rand[1] + Pr), sz), 2] = 0
        loc.append(rand)
    return mp, loc

# Update the graph (simulation happens: killing, protection, reproducing)
def update(sloc, rdloc, ploc, oldmp, sz, repros, reprord, reprop, r):
    mp = np.full((sz+1, sz+1, 3), 1)
    nsloc = []
    nploc = []
    nrdloc = []
    for a in sloc:
        if oldmp[a[0], a[1], 2] > 10 or oldmp[a[0], a[1], 1] > 10:
            mp[a[0], a[1], 2] = 255
            mp[a[0], a[1], 1] = 0
            mp[a[0], a[1], 0] = 0
            nsloc.append(a)
            for i in range(repros):
                rand = np.random.randint(low=-r, high=r, size=2)
                x = a[0]+rand[0]
                y = a[1]+rand[1]
                offspring = np.asarray([x,y])
                offspring = np.clip(offspring, 0, 200)
                nsloc.append(offspring)
    for c in ploc:
        nploc.append(c)
        mp[c[0], c[1], 2] = 0
        mp[c[0], c[1], 1] = 1
        mp[c[0], c[1], 0] = 255
        for j in range(reprop):
            rand = np.random.randint(low=-r, high=r, size=2)
            x = c[0] + rand[0]
            y = c[1] + rand[1]
            offspring = np.asarray([x, y])
            offspring = np.clip(offspring, 0, 200)
            if mp[offspring[0], offspring[1], :].tolist() == [1, 1, 1]:
                nploc.append(offspring)
    for b in rdloc:
        nrdloc.append(b)
        mp[b[0], b[1], 2] = 0
        mp[b[0], b[1], 1] = 255
        mp[b[0], b[1], 0] = 0
        for j in range(reprord):
            rand = np.random.randint(low=-r, high=r, size=2)
            x = b[0] + rand[0]
            y = b[1] + rand[1]
            offspring = np.asarray([x, y])
            offspring = np.clip(offspring, 0, 200)
            if mp[offspring[0], offspring[1], :].tolist() == [1, 1, 1]:
                nrdloc.append(offspring)
    return mp, nsloc, nploc, nrdloc

# Generate new graphs for next round based on the result of last round
def new_graph(loc, sz, Pr, RDr, x):
    mp = np.full((sz+1, sz+1, 3), 1)
    for i in loc:
        if x == 2:
            mp[i[0], i[1], x] = 255
            mp[i[0], i[1], 0] = 0
            mp[i[0], i[1], 1] = 0
        elif x == 1:
            mp[np.maximum((i[0]-RDr), 0):np.minimum((i[0] + RDr), sz),
            np.maximum((i[1]-RDr), 0):np.minimum((i[1] + RDr), sz), x] = 255

            mp[np.maximum((i[0] - RDr), 0):np.minimum((i[0] + RDr), sz),
            np.maximum((i[1] - RDr), 0):np.minimum((i[1] + RDr), sz), 0] = 0

            mp[np.maximum((i[0] - RDr), 0):np.minimum((i[0] + RDr), sz),
            np.maximum((i[1] - RDr), 0):np.minimum((i[1] + RDr), sz), 2] = 0
        elif x == 0:
            mp[np.maximum((i[0] - Pr), 0):np.minimum((i[0] + Pr), sz),
            np.maximum((i[1] - Pr), 0):np.minimum((i[1] + Pr), sz), x] = 255

            mp[np.maximum((i[0] - Pr), 0):np.minimum((i[0] + Pr), sz),
            np.maximum((i[1] - Pr), 0):np.minimum((i[1] + Pr), sz), 1] = 1

            mp[np.maximum((i[0] - Pr), 0):np.minimum((i[0] + Pr), sz),
            np.maximum((i[1] - Pr), 0):np.minimum((i[1] + Pr), sz), 2] = 0
    return mp

# Main method. Save process and result graph of each round and eventually generate movies of simulation.
def main(round, init_num, sz, Pr, RDr, Srepro, RDrepro, Prepro, r):
    S, Sloc = init_placement(sz, init_num, 2, Pr, RDr)
    RD, RDloc = init_placement(sz, init_num, 1, Pr, RDr)
    P, Ploc = init_placement(sz, init_num, 0, Pr, RDr)
    result = np.multiply((S+RD-1), P)
    result_view = result.repeat(5, axis=0).repeat(5, axis=1)
    cv2.imwrite('round-1.png', result_view)
    updatedmap, nsloc, nploc, nrdloc = update(Sloc, RDloc, Ploc, result, sz, Srepro, RDrepro, Prepro, r)
    updatedmap_view = updatedmap.repeat(5, axis=0).repeat(5, axis=1)
    cv2.imwrite('result-1.png', updatedmap_view)

    height, width, layers = updatedmap_view.shape
    result_video = cv2.VideoWriter('result_video.mov', -1, 1, (width, height))
    rimg = cv2.imread('result-1.png')
    result_video.write(rimg)

    height, width, layers = result_view.shape
    process_video = cv2.VideoWriter('process_video.mov', -1, 1, (width, height))
    pimg = cv2.imread('round-1.png')
    process_video.write(pimg)

    for i in range(round-1):
        S = new_graph(nsloc, sz, Pr, RDr, 2)
        RD = new_graph(nrdloc, sz, Pr, RDr, 1)
        P = new_graph(nploc, sz, Pr, RDr, 0)
        new = np.multiply((S+RD-1), P)
        new_view = new.repeat(5, axis=0).repeat(5, axis=1)
        cv2.imwrite('round-{}.png'.format(str(i+2)), new_view)
        pimg = cv2.imread('round-{}.png'.format(str(i+2)))
        process_video.write(pimg)

        updatedmap, nsloc, nploc, nrdloc = update(nsloc, nrdloc, nploc, new, sz, Srepro, RDrepro, Prepro, r)
        updatedmap_view = updatedmap.repeat(5, axis=0).repeat(5, axis=1)
        cv2.imwrite('result-{}.png'.format(str(i+2)), updatedmap_view)
        rimg = cv2.imread('result-{}.png'.format(str(i+2)))
        result_video.write(rimg)
    cv2.destroyAllWindows()
    process_video.release()
    result_video.release()

if __name__ == "__main__":
    # Run
    main(20, 15, sz, Pr, RDr, Srepro, RDrepro, Prepro, r)


from main.bot import send_message
from main.parser import parser_factory
from main.service import get_employees_info

def main():
    """
    Project entry point.
    """
    parser = parser_factory()
    args = parser.parse_args()

    data = get_employees_info(next_day=args.next_day)
    send_message(employee_data=data, next_day=args.next_day)

if __name__ == "__main__":
    main()


"""add default atat role

Revision ID: 58115a0c85ac
Revises: 428edc7b735c
Create Date: 2018-07-19 17:13:32.881309

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.orm.session import Session

from authz.models.role import Role
from authz.models.permissions import Permissions

# revision identifiers, used by Alembic.
revision = '58115a0c85ac'
down_revision = '428edc7b735c'
branch_labels = None
depends_on = None

def upgrade():
    session = Session(bind=op.get_bind())
    mission_owner_role = Role(
        name='default',
        description='',
        permissions=[
            Permissions.REQUEST_JEDI_WORKSPACE,
        ]
    )
    session.add(mission_owner_role)
    session.commit()

def downgrade():
    db = op.get_bind()
    db.execute("DELETE FROM roles WHERE name = 'default'")


from sklearn.svm import SVR
from data_preprocessing import x_list,y
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import Ridge, LinearRegression
import numpy as np
import warnings

x = x_list[0][1]
x_rs_cd = x_list[5][1]
x_std = x_list[2][1]
x_cd_std = x_list[3][1]
x_rs = x_list[4][1]

def tuning(x,y,model,param_grid):
    best_params = []
    model = model()
    scoring = 'neg_mean_squared_error'
    grid = GridSearchCV(estimator=model, param_grid=param_grid, verbose=10, n_jobs=3, return_train_score=False)
    grid.fit(x,y)
    best_params.append(grid.best_params_)
    print(best_params)

def model_evaluation(x,y,model):
    x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.33,random_state=0)
    model.fit(x_train, y_train)
    y_pred = model.predict(x_test)
    y_pred_t = model.predict(x_train)
    result = mean_squared_error(y_test, y_pred)
    result_t = mean_squared_error(y_train, y_pred_t)
    print('Test Result:', result)
    print('\nTrain Result:', result_t)

if __name__ == '__main__':
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')

        model_evaluation(x,y,LinearRegression())


import math
import numbers
import warnings
from typing import List

import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator

try:
    from sklearn import get_config as sklearn_get_config
except ImportError:  # pragma: no cover
    sklearn_get_config = None

from ... import options
from ...core import enter_mode
from ...typing import TileableType
from ...dataframe import DataFrame, Series
from ...dataframe.core import DATAFRAME_TYPE, SERIES_TYPE
from ...tensor import tensor as astensor
from ...utils import parse_readable_size

def convert_to_tensor_or_dataframe(item):
    if isinstance(item, (DATAFRAME_TYPE, pd.DataFrame)):
        item = DataFrame(item)
    elif isinstance(item, (SERIES_TYPE, pd.Series)):
        item = Series(item)
    else:
        item = astensor(item)
    return item

def concat_chunks(chunks):
    tileable = chunks[0].op.create_tileable_from_chunks(chunks)
    return tileable.op.concat_tileable_chunks(tileable).chunks[0]

def copy_learned_attributes(from_estimator: BaseEstimator, to_estimator: BaseEstimator):
    attrs = {
        k: v
        for k, v in vars(from_estimator).items()
        if k.endswith("_") or k.startswith("_")
    }
    for k, v in attrs.items():
        setattr(to_estimator, k, v)

def is_scalar_nan(x):
    """Tests if x is NaN.

    This function is meant to overcome the issue that np.isnan does not allow
    non-numerical types as input, and that np.nan is not float('nan').

    Parameters
    ----------
    x : any type

    Returns
    -------
    boolean

    Examples
    --------
    >>> is_scalar_nan(np.nan)
    True
    >>> is_scalar_nan(float("nan"))
    True
    >>> is_scalar_nan(None)
    False
    >>> is_scalar_nan("")
    False
    >>> is_scalar_nan([np.nan])
    False
    """
    return isinstance(x, numbers.Real) and math.isnan(x)

def get_chunk_n_rows(row_bytes, max_n_rows=None, working_memory=None):
    """Calculates how many rows can be processed within working_memory

    Parameters
    ----------
    row_bytes : int
        The expected number of bytes of memory that will be consumed
        during the processing of each row.
    max_n_rows : int, optional
        The maximum return value.
    working_memory : int or float, optional
        The number of rows to fit inside this number of MiB will be returned.
        When None (default), the value of
        ``sklearn.get_config()['working_memory']`` is used.

    Returns
    -------
    int or the value of n_samples

    Warns
    -----
    Issues a UserWarning if ``row_bytes`` exceeds ``working_memory`` MiB.
    """

    if working_memory is None:  # pragma: no cover
        working_memory = options.learn.working_memory
        if working_memory is None and sklearn_get_config is not None:
            working_memory = sklearn_get_config()["working_memory"]
        elif working_memory is None:
            working_memory = 1024

    if isinstance(working_memory, int):
        working_memory *= 2**20
    else:
        working_memory = parse_readable_size(working_memory)[0]

    chunk_n_rows = int(working_memory // row_bytes)
    if max_n_rows is not None:
        chunk_n_rows = min(chunk_n_rows, max_n_rows)
    if chunk_n_rows < 1:  # pragma: no cover
        warnings.warn(
            "Could not adhere to working_memory config. "
            "Currently %.0fMiB, %.0fMiB required."
            % (working_memory, np.ceil(row_bytes * 2**-20))
        )
        chunk_n_rows = 1
    return chunk_n_rows

@enter_mode(build=True)
def sort_by(
    tensors: List[TileableType], by: TileableType, ascending: bool = True
) -> List[TileableType]:
    # sort tensors by another tensor
    i_to_tensors = {i: t for i, t in enumerate(tensors)}
    if by not in tensors:
        by_name = len(i_to_tensors)
        i_to_tensors[by_name] = by
    else:
        by_name = tensors.index(by)
    df = DataFrame(i_to_tensors)
    sorted_df = df.sort_values(by_name, ascending=ascending)
    return [sorted_df[i].to_tensor() for i in range(len(tensors))]


from __future__ import print_function

import argparse
import os.path
import distutils.util

class ComLine():
	'Class for implementing command line options'

	def __init__(self, args):
		parser = argparse.ArgumentParser()
		parser._action_groups.pop()
		required = parser.add_argument_group('Required arguments (only one of -v, -b, or -p is required)')
		optional = parser.add_argument_group('Optional arguments')
		opt_admix = parser.add_argument_group('Admixture optional arguments')
		opt_filt = parser.add_argument_group('Filtering arguments (compatible with VCFtools and PLINK)')
		opt_vcf = parser.add_argument_group('VCFtools filtering arguments')
		required.add_argument("-m", "--popmap",
							dest='popmap',
							required=True,
							help="Specify a tab-delimited population map (sample -> population)"
		)
		required.add_argument("-v", "--vcf",
							dest='vcf',
							help="Specify a vcf file for input."
		)
		opt_admix.add_argument("-k", "--minK",
							dest='minK',
							type=int,
							default=1,
							help="minimum K value."
		)
		opt_admix.add_argument("-K", "--maxK",
							dest='maxK',
							type=int,
							default=20,
							help="maximum K value."
		)
		required.add_argument("-p", "--ped",
							dest='ped',
							help="Specify the prefix for a text plink file. File should have been encoded in plink using the --recode12 option. This is under active development. Use at your own risk."
		)
		required.add_argument("-b", "--bed",
							dest='bed',
							help="Specify the prefix for a binary plink file. This is under active development. Use at your own risk."
		)
		opt_filt.add_argument("-M", "--mac",
							dest='mac',
							type=int,
							default=0,
							help="Enter the minimum count for the minor allele filter."
		)
		opt_filt.add_argument("-a", "--maf",
							dest='maf',
							type=float,
							default=0.0,
							help="Enter the minimum frequency for the minor allele filter."
		)
		optional.add_argument("-n", "--np",
							dest='np',
							type=int,
							default=1,
							help="Number of processors."
		)
		opt_filt.add_argument("-t", "--thin",
							dest='thin',
							type=int,
							default=0,
							help="Use VCFtools or PLINK to thin out loci falling within the specified proximity to one another."
		)
		opt_vcf.add_argument("-C", "--indcov",
							dest='indcov',
							type=float,
							default=0.9,
							help="Specify the maximum allowable missing data per individual"
		)
		opt_filt.add_argument("-S", "--snpcov",
							dest='snpcov',
							type=float,
							default=0.1,
							help="Specify the allowable proportion of missing data per SNP. 0 allows sites that are completely missing and 1 indicates no missing data allowed."
		)
		opt_admix.add_argument("-c", "--cv",
							dest='cv',
							type=int,
							default=20,
							help="Specify the cross-validation number for admixture program"
		)
		opt_admix.add_argument("-R", "--rep",
							dest='rep',
							type=int,
							default=20,
							help="Number of replicates per K."
		)
		opt_vcf.add_argument("-B", "--bi",
							dest='bi',
							action='store_true',
							help="Turn off filter for biallelic SNPs."
		)

		self.args = parser.parse_args()

		#check that combinations of command line options are valid
		booleans=[self.args.vcf, self.args.ped, self.args.bed]
		if self.xOrMoreAreTrue(booleans) > 1:
			print("ERROR: Only one of a bed, ped, or vcf file can be used as input.")
			print("Exiting program...")
			print("")
			raise SystemExit
		elif any([self.args.vcf, self.args.ped, self.args.bed]):
			if self.args.vcf:
				print("VCF input option used.")
			if self.args.ped:
				print("PLINK ped input option used.")
				print("Continuing with all filtering options disabled.")
			if self.args.bed:
				print("PLINK bed input option used.")
				print("Continuing with all filtering options disabled.")
		else:
			print("ERROR: Must specify either a VCF file or a PLINK file (bed or ped) as input.")
			print("Exiting program...")
			print("")
			raise SystemExit

		#check if files exist
		print("Checking if popmap file exists...")
		self.exists( self.args.popmap )
		if self.args.vcf:
			print("Checking if VCF file exists...")
			self.exists( self.args.vcf )
		if self.args.ped:
			print("Checking if plink .ped file exists...")
			plinkPed = self.args.ped + ".ped"
			self.exists( plinkPed )
			print("Checking if plink .map file exists...")
			plinkMap = self.args.ped + ".map"
			self.exists( plinkMap )
		if self.args.bed:
			print("Checking if plink .bed file exists...")
			plinkBed = self.args.bed + ".bed"
			self.exists( plinkBed )
			print("Checking if plink .bim file exists...")
			plinkBim = self.args.bed + ".bim"
			self.exists( plinkBim )
			print("Checking if plink .fam file exists...")
			plinkFam = self.args.bed + ".fam"
			self.exists( plinkFam )

	def exists(self, filename):
		if( os.path.isfile(filename) != True ):
			print(filename, "does not exist")
			print("Exiting program...")
			print("")
			raise SystemExit
		else:
			print("Found.")
			print("")

	def xOrMoreAreTrue(self, booleans):
		count = 0
		for boolean in booleans:
			if(boolean):
				count += 1
		return count


#-*- coding: utf-8 -*-
def what_type(x):
    """타입을 확인하는 함수

    """
    data_type = 'null'
    if(isinstance(x, int)):
        data_type = 'int'
    elif(isinstance(x, float)):
        data_type = 'float'
    elif(isinstance(x, basestring)):
        data_type = 'str'
        if(isinstance(x, unicode)):
            data_type = 'unicode'
    else:
        data_type = 'not defined'
    return data_type

def test_what_type():
    assert 'int' == what_type(1)
    assert 'float'  == what_type(2.2)
    assert 'str' == what_type('abc')
    assert 'unicode' == what_type(u'abc')


from flask import Flask
from flask_restful import Resource, Api
from flask_restful_swagger import swagger
from helper import Database, BGGAPI, RecommendationEngine
import turicreate as tc

app = Flask(__name__)
api = Api(app)

item_model = tc.load_model("models/itemsimilarity_2020-03-15")
factorization_model = tc.load_model("models/factorization_2020-04-11")

db, dbuser, dbhost = "ashok", "ashok", "localhost"
database = Database(db, dbuser, dbhost)
engine_item = RecommendationEngine(item_model)
engine_factorization = RecommendationEngine(factorization_model)

bggapi = BGGAPI()

class HelloWorld(Resource):
    def get(self):
        return {"hello": "world"}

class UserGames(Resource):
    def get(self, username):
        usergames = database.get_usergames(username)

        if len(usergames) > 0:
            user_found = True #user found in our internal database
        else:
            usergames = bggapi.get_usergames(username) #games for user downloaded from API

        return {
            "totalgames": len(usergames),
            "data": usergames,
        }

class GameInfo(Resource):
    def get(self, gameid):
        return

class UserRecommendations(Resource):
    def get(self, username):
        gameids, ranks = engine_factorization.recommendations(username, 10)
        gameinfo = database.games_info(gameids)

        recos = []

        for game in gameinfo:
            game["rank"] = ranks[gameids.index(game["gameid"])]
            recos.append(game)

        return {
            "data": recos
        }

class SimilarGames(Resource):
    def get(self, gameid):
        return

class SearchGame(Resource):
    def get(self, search):
        return

class PopularGames(Resource):
    def get(self):
        return

class GameCategories(Resource):
    def get(self, category, sorting):
        if category not in ("mechanic", "category"):
            return {
                "error": "type must be in [mechanic, category]"
            }

        if sorting not in ("alphabetical", "popular"):
            return {
                "error": "sorting should be in [alphabetical, popular]"
            }

        categories = database.get_categories(category, sorting)

        return {
            "totalmechanics": len(categories),
            "data": categories
            }

api.add_resource(HelloWorld, "/")
api.add_resource(GameCategories, "/api/categories/type=<string:category>&sort=<string:sorting>")
api.add_resource(UserGames, "/api/user/<string:username>")
api.add_resource(GameInfo, "/api/game/<string:gameid>")
api.add_resource(SimilarGames, "/api/game/similar/<string:gameid>")
api.add_resource(UserRecommendations, "/api/user/<string:username>/recos")

if __name__ == "__main__":
    app.run(debug=True, port=5004)


from lib.packet.packet_base import Serializable
from lib.defines import OPAQUE_FIELD_LEN
from lib.util import Raw
from typing import Dict, List, Sized, Tuple

class OpaqueField(Serializable):
    LEN = OPAQUE_FIELD_LEN

class OpaqueFieldList():
    def __init__(self, order: Tuple[str, str, str, str, str, str]) -> None:  # pragma: no cover
        """
        :param list order:
            A list of tokens that define the order of the opaque field labels.
            E.g. ``[UP_IOF, UP_HOFS]`` defines that the up-segment info opaque
            field comes before the up-segment hop opaque fields.
        """
        self._order = order
        self._labels: Dict[str, List[OpaqueField]] = {}
        for label in order:
            self._labels[label] = []

    def __len__(self) -> int:
        ...

    def get_by_idx(self, idx: int) -> OpaqueField:
        ...
        # """
        # Get an OF by index. The index follows the order supplied when the
        # :class:`OpaqueFieldList` object was created.
        #
        # :param int idx: The index to fetch.
        # :returns: The OF at that index.
        # :rtype: :class:`OpaqueField`
        # :raises:
        #     SCIONIndexError: if the index is negative, or too large.
        # """
        # if idx < 0:
        #     raise SCIONIndexError("Requested OF index (%d) is negative" % idx)
        # offset = idx
        # for label in self._order:
        #     group = self._labels[label]
        #     if offset < len(group):
        #         return group[offset]
        #     offset -= len(group)
        # raise SCIONIndexError("Requested OF index (%d) is out of range (max %d)"
        #                       % (idx, len(self) - 1))

class HopOpaqueField(OpaqueField):
    NAME = "HopOpaqueField"
    MAC_LEN = 3  # MAC length in bytes.
    MAC_BLOCK_LEN = 16

    def __init__(self, raw: Raw=None) -> None:  # pragma: no cover
        self.xover = False
        self.verify_only = False
        self.forward_only = False
        self.recurse = False
        self.exp_time = 0
        self.ingress_if = 0
        self.egress_if = 0
        self.mac = bytes(self.MAC_LEN)

    def calc_mac(self, key: bytes, ts: int, prev_hof:'HopOpaqueField'=None) -> None:
        ...

    def set_mac(self, key: bytes, ts: int, prev_hof:'HopOpaqueField'=None) -> bytes:
        ...

    def verify_mac(self, key: bytes, ts: int, prev_hof:'HopOpaqueField'=None) -> bool:  # pragma: no cover
        ...

    @staticmethod
    def from_values(exp_time: int, ingress_if: int=0, egress_if: int=0,
                    mac: bytes=None, xover: bool=False, verify_only: bool=False,
                    forward_only: bool=False, recurse: bool=False) -> 'HopOpaqueField':
        ...

class InfoOpaqueField(OpaqueField):
    def __init__(self) -> None:  # pragma: no cover
        self.up_flag = False
        self.shortcut = False
        self.peer = False
        self.timestamp = 0
        self.isd = 0
        self.hops = 0


from __future__ import print_function
from __future__ import division

import os
import sys
import time
import os.path as osp
import numpy as np

import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn

from args import argument_parser, image_dataset_kwargs
from torchreid.multi_data_manager import ImageDataManager
from torchreid import models
from torchreid.utils.iotools import check_isfile
from torchreid.utils.avgmeter import AverageMeter
from torchreid.utils.loggers import Logger
from torchreid.utils.torchtools import count_num_param
from torchreid.utils.reidtools import visualize_ranked_results
from torchreid.eval_metrics import evaluate

import logging
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'CRITICAL'))

# global variables
parser = argument_parser()
args = parser.parse_args()

os.environ['TORCH_HOME'] = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '.torch'))

def accuracy(output, target, topk=(1,)):
    """Computes the accuracy over the k top predictions for
    the specified values of k.
    Args:
        output (torch.Tensor): prediction matrix with shape (batch_size, num_classes).
        target (torch.LongTensor): ground truth labels with shape (batch_size).
        topk (tuple, optional): accuracy at top-k will be computed. For example,
            topk=(1, 5) means accuracy at top-1 and top-5 will be computed.
    Returns:
        list: accuracy at top-k.
    Examples::
        >>> from torchreid import metrics
        >>> metrics.accuracy(output, target)
    """
    maxk = max(topk)
    batch_size = target.size(0)

    if isinstance(output, (tuple, list)):
        output = output[0]

    _, pred = output.topk(maxk, 1, True, 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).float().sum(0, keepdim=True)
        acc = correct_k.mul_(100.0 / batch_size)
        res.append(acc)

    return res

def get_criterion(num_classes: int, use_gpu: bool, args):

    if args.criterion == 'htri':

        from torchreid.losses.hard_mine_triplet_loss import TripletLoss
        criterion = TripletLoss(num_classes, vars(args), use_gpu)

    elif args.criterion == 'xent':

        from torchreid.losses.cross_entropy_loss import CrossEntropyLoss
        criterion = CrossEntropyLoss(num_classes, use_gpu=use_gpu, label_smooth=args.label_smooth)
    else:
        raise RuntimeError('Unknown criterion {}'.format(args.criterion))

    return criterion

def main():
    global args

    if not args.evaluate:
        raise RuntimeError('Test only!')

    torch.manual_seed(args.seed)
    if not args.use_avai_gpus:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_devices
    use_gpu = torch.cuda.is_available()
    if args.use_cpu:
        use_gpu = False
    log_name = 'log_test.txt' if args.evaluate else 'log_train.txt'
    log_fn = osp.join(args.save_dir, log_name)
    sys.stderr = sys.stdout = Logger(log_fn)
    print("==========\nArgs:{}\n==========".format(args))

    if use_gpu:
        print("Currently using GPU {}".format(args.gpu_devices))
        cudnn.benchmark = True
        torch.cuda.manual_seed_all(args.seed)
    else:
        print("Currently using CPU, however, GPU is highly recommended")

    print("Initializing image data manager")
    dm = ImageDataManager(use_gpu, **image_dataset_kwargs(args))
    trainloader, testloader_dict = dm.return_dataloaders()

    print("Initializing model: {}".format(args.arch))
    model = models.init_model(name=args.arch, num_classes=dm.num_train_pids, loss={'xent'}, use_gpu=use_gpu, args=vars(args))
    print(model)
    print("Model size: {:.3f} M".format(count_num_param(model)))

    if args.load_weights and check_isfile(args.load_weights):
        # load pretrained weights but ignore layers that don't match in size
        try:
            checkpoint = torch.load(args.load_weights)
        except Exception as e:
            print(e)
            checkpoint = torch.load(args.load_weights, map_location={'cuda:0': 'cpu'})

        pretrain_dict = checkpoint['state_dict']
        model_dict = model.state_dict()
        pretrain_dict = {k: v for k, v in pretrain_dict.items() if k in model_dict and model_dict[k].size() == v.size()}
        model_dict.update(pretrain_dict)
        model.load_state_dict(model_dict)
        print("Loaded pretrained weights from '{}'".format(args.load_weights))

    if args.resume and check_isfile(args.resume):
        checkpoint = torch.load(args.resume)
        state = model.state_dict()
        state.update(checkpoint['state_dict'])
        model.load_state_dict(state)
        # args.start_epoch = checkpoint['epoch'] + 1
        print("Loaded checkpoint from '{}'".format(args.resume))
        print("- start_epoch: {}\n- rank1: {}".format(args.start_epoch, checkpoint['rank1']))

    if use_gpu:
        model = nn.DataParallel(model).cuda()

    if args.evaluate:
        print("Evaluate only")

        for name in args.target_names:
            print("Evaluating {} ...".format(name))
            distmat = test(model, testloader_dict[name], use_gpu, return_distmat=True)

            if args.visualize_ranks:
                visualize_ranked_results(
                    distmat, dm.return_testdataset_by_name(name),
                    save_dir=osp.join(args.save_dir, 'ranked_results', name),
                    topk=20
                )
        return

def test(model, loaders, use_gpu, ranks=[1, 5, 10, 20], return_distmat=True):

    batch_time = AverageMeter()

    model.eval()

    def eval_set(name, loader):

        with torch.no_grad():
            qf, q_pids, q_camids, q_paths = [], [], [], []

            enumerator = enumerate(loader)

            for batch_idx, package in enumerator:
                end = time.time()

                (imgs, pids, camids, paths) = package
                if use_gpu:
                    imgs = imgs.cuda()

                features = model(imgs)[0]

                batch_time.update(time.time() - end)

                features = features.data.cpu()
                qf.append(features)
                q_pids.extend(pids)
                q_camids.extend(camids)
                q_paths.extend(paths)
            qf = torch.cat(qf, 0)
            q_pids = np.asarray(q_pids)
            q_camids = np.asarray(q_camids)

            print("Extracted features for {} set, obtained {}-by-{} matrix".format(name, qf.size(0), qf.size(1)))

            return qf, q_pids, q_camids

    results = {}
    for name, dct in loaders.items():
        results[name] = (eval_set('{} query'.format(name), dct['query']), eval_set('{} gallery'.format(name), dct['gallery']))

    def eval_result(gr, qr):

        gf, g_pids, g_camids = gr
        qf, q_pids, q_camids = qr

        m, n = qf.size(0), gf.size(0)
        distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \
            torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t()
        distmat.addmm_(1, -2, qf, gf.t())
        distmat = distmat.numpy()

        print("Computing CMC and mAP")
        cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids, use_metric_cuhk03=args.use_metric_cuhk03)

        print("Results ----------")
        print("mAP: {:.2%}".format(mAP))
        print("CMC curve")
        for r in ranks:
            print("Rank-{:<3}: {:.2%}".format(r, cmc[r - 1]))
        print("------------------")

        return [mAP, *cmc]

    metrics = []
    for name, (qr, gr) in results.items():
        metrics.append(eval_result(gr, qr))
    metrics = np.average(np.array(metrics), axis=0)
    mAP, *cmc = metrics

    print('====> Average Result')
    print("Results ----------")
    print("mAP: {:.2%}".format(mAP))
    print("CMC curve")
    for r in ranks:
        print("Rank-{:<3}: {:.2%}".format(r, cmc[r - 1]))
    print("------------------")

    return

if __name__ == '__main__':
    main()


from sys import stdin
from queue import Queue

def run(testcase=1):
    for _ in range(testcase):
        solve()

def inputs():
    """
    Input format
    S
    T

    params:
        S  start word  ( 1 <= len(S) <= 999)
        T  target word ( 2 <= len(T) <= 1000, len(S) < len(T))

    """
    S = stdin.readline().rstrip()
    T = stdin.readline().rstrip()

    return list(S), list(T)

def solve():
    S, T = inputs()

    while len(S) != len(T):
        if T[-1] == "A":
            T.pop()
        else:
            T.pop()
            T = T[::-1]

    print(int(S == T))

run()


from re import compile as compile_regex
from re import DOTALL
from secrets import token_hex
from typing import Optional

from plotly.graph_objects import Figure as _Figure

from .grid_object import GridObject
from .._utils import check_type

class PlotlyFigure(GridObject):
    """Represents a Plotly figure, with an additional function to return the Plotly.newPlot(...) JS code.

    Parameters
    ----------
    fig: plotly.graph_objects.Figure
        A Plotly Figure object.
    row: int
        The grid row in which to place this plot.
    column: int
        The grid column in which to place this plot.
    row_span: optional, int
        The number of rows for this plot to span (defaults to `1`).
    col_span: optional, int
        The number of columns for this plot to span (defaults to `1`).
    css_class: str, optional
        The name of the CSS class (or classes) to apply to this object.
    config: optional, dict
        A dictionary containing plot configuration options to be passed to Plotly.js.
    """

    def __init__(self,
                 fig: _Figure,
                 row: int,
                 column: int,
                 row_span: int = 1,
                 col_span: int = 1,
                 css_class: Optional[str] = None,
                 config: Optional[dict] = None
                 ):
        check_type("fig", fig, _Figure)
        self.fig = fig
        self.config = config

        self._check_and_set(row, column, row_span, col_span, css_class)

        # Generate a better ID for this figure - we'll use this later.
        self.fig_id = token_hex(5)

    def get_plot_js(self) -> str:
        """Get the Javascript Plotly.newPlot(...) function for this plot. The Figure object is converted to its full
        HTML presentation via the fig.to_html(...) function, from which the relevant Javascript is extracted.

        Note: the required
 tags for the plot are generated by the `get_div()` function.

        Returns
        -------
        str
            The Plotly.newPlot(...) function for this plot.
        """
        plotly_html = self.fig.to_html(include_plotlyjs=False, full_html=False, auto_play=False)
                                       #default_width='100%', default_height='100%')

        # Only keep the Plotly.newPlot(...) part of the HTML string above - it contains everything we need.
        # Use a quick hit of RegEx.
        regex = compile_regex("Plotly.newPlot\(.*\)", flags=DOTALL)
        plotly_str = regex.findall(plotly_html)[0]

        # Extract the div id - we'll replace it with something more sensible.
        regex = compile_regex('div id=\".*?\"')
        div_id = regex.findall(plotly_html)[0]
        orig_id = compile_regex('\".*"').findall(div_id)[0].replace('"', '')

        # Replace the generated div id with the shorter figure ID.
        plotly_js_str = plotly_str.replace(orig_id, self.fig_id)
        return plotly_js_str

    def get_purge_js(self) -> str:
        """Returns the JS to remove/purge this plot from the screen."""
        return f'Plotly.purge("{self.fig_id}");'

    def get_div(self) -> str:
        """Get the required

 HTML tags to display this plot.

        Returns
        -------
        str
        """
        div_str = f'

'
        return div_str

    def __str__(self):
        return self.get_div()


import requests
from azure.cognitiveservices.language.textanalytics import TextAnalyticsClient
from msrest.authentication import CognitiveServicesCredentials
from pprint import pprint
import os
import re

sample_query_response = {
    "items": [
        {
            "tags": [
                "python",
                "iterator",
                "generator",
                "yield",
                "coroutine"
            ],
            "answers": [
                {
                    "owner": {
                        "user_id": 8458,
                        "display_name": "Douglas Mayle"
                    },
                    "score": 326,
                    "creation_date": 1224800643,
                    "answer_id": 231778,
                    "body": "
yield is just like return - it returns whatever you tell it to (as a generator). The difference is that the next time you call the generator, execution starts from the last call to the yield statement. Unlike return, the stack frame is not cleaned up when a yield occurs, however control is transferred back to the caller, so its state will resume the next time the function is called.
\n\n
In the case of your code, the function get_child_candidates is acting like an iterator so that when you extend your list, it adds one element at a time to the new list.
\n\n
list.extend calls an iterator until it's exhausted. In the case of the code sample you posted, it would be much clearer to just return a tuple and append that to the list.
\n"
                },
                {
                    "owner": {
                        "user_id": 22656,
                        "display_name": "Jon Skeet"
                    },
                    "score": 188,
                    "creation_date": 1224800766,
                    "answer_id": 231788,
                    "body": "
It's returning a generator. I'm not particularly familiar with Python, but I believe it's the same kind of thing as C#'s iterator blocks if you're familiar with those.
\n\n
The key idea is that the compiler/interpreter/whatever does some trickery so that as far as the caller is concerned, they can keep calling next() and it will keep returning values - as if the generator method was paused. Now obviously you can't really \"pause\" a method, so the compiler builds a state machine for you to remember where you currently are and what the local variables etc look like. This is much easier than writing an iterator yourself.
\n"
                }
            ],
            "owner": {
                "user_id": 18300,
                "display_name": "Alex. S."
            },
            "accepted_answer_id": 231855,
            "answer_count": 41,
            "score": 10146,
            "creation_date": 1224800471,
            "question_id": 231767,
            "title": "What does the "yield" keyword do?"
        }
    ]
}

class SentimentAnalyzer:
  def __init__(self):
        self.client = self.authenticateClient()

  # Creates client for sending requests to azure textanalytics api
  def authenticateClient(self):
    # TODO: Fill in the endpoint and key from Azure
    endpoint = ''
    key = ''

    credentials = CognitiveServicesCredentials(key)
    text_analytics_client = TextAnalyticsClient(endpoint=endpoint, credentials=credentials)
    return text_analytics_client

  # creates the 'documentsList' which will be sent to azure, for a set of answers.
  def createDocumentsList(self, answers):
      count = 1
      documentsList = []
      for answer in answers:
          count += 1
          document = self.createDocument(answer, count)
          documentsList.append(document)

      return documentsList

  # creates a document for one specific answer
  def createDocument(self, answer, count):
      body = self.removeMarkUps(answer["body"])
      # to get sentiment linked to answer_id use `str(answer["answer_id"])`` instead of str(count)`
      document = {
          "language": "en",
          "id": str(answer["answer_id"]),
          "text": body
      }
      return document

  # max documentList size is 1000 elements/ids and documents can have no more than 5120 characters
  # analyzes the sentiments of a list of documents (in our case answers), and returns the api response
  def getSentimentAnalysis(self, documents):
      response = self.client.sentiment(documents=documents)
      return response

  # analyzes one post and the corresponding answers. analyze means: "what is the sentiment score of the answers?"
  # input:
  #     the json of a stackexchange query, in the format s.t.:
  #          one item in the items list is one question with all the answers in an answer list
  # return: returns a list of posts with the corresponding sentiment analysis
  def analyzeFullPostWithAnswers(self, batch):
      multiplePostsWithAnalysis = []
      for item in batch["items"]:
          response = self.getSentimentAnalysis(self.createDocumentsList(item["answers"]))
          postWithAnalysis = {
            "question_id": item["question_id"],
            "user_id": item["owner"]["user_id"],
            "response_with_scores": self.azureResponseToJson(response)
          }
          # self.printRespons(response)
          pprint(postWithAnalysis)
          multiplePostsWithAnalysis.append(postWithAnalysis)

      return multiplePostsWithAnalysis

  # Formats the azure api response to a json object and returns it
  def azureResponseToJson(self, response):
    answer_list = []
    for document in response.documents:
        answer = {"answer_id": document.id, "sentiment_score": "{:.2f}".format(document.score)}
        answer_list.append(answer)

    return answer_list

  # helper function to remove code from text-/answer-body
  def remove_code_from_posts(self, raw_html):
      clean_up = re.sub(".*?", "", raw_html)
      return clean_up

  # helper function to remove markup from text-/answer-body
  def removeMarkUps(self, markUpText):
      cleanr = re.compile('<.*?>')
      cleantext = re.sub(cleanr, '', self.remove_code_from_posts(markUpText))
      return cleantext

sa = SentimentAnalyzer()
analyzedWithSentiments = sa.analyzeFullPostWithAnswers(sample_query_response)
pprint(analyzedWithSentiments)


import string

from .numbers_processing import retrieve_ordinal, check_convert_roman
from .numbers_processing import contain_numbers, extract_number_suffix, extract_number
from autocorrect import Speller
from spellchecker import SpellChecker
from . import settings
from .package_logging import log

"""
Module that prepossesses and cleans the date string
"""

def keywords_to_string(keywords):
    """
    Takes the keyword dictionary and transforms the existing keywords into a correctly formatted string

    :param keywords: Dictionary of keywords
    :type keywords: dict
    :return: Correctly formatted string
    :rtype: str
    """
    if keywords["part"]["active"]:
        return " (" + " ".join(keywords["part"]["active"]) + ")"
    elif keywords["split"]["active"] is not None:
        return " (" + str(keywords["ordinal"]["active"]) + " " + str(keywords["split"]["active"]) + ")"
    return ""

def remove_stopwords(text):
    """
    Removes stopwords from the string

    :param text: String to parse and clean
    :type text: list
    :return: Cleaned string
    :rtype: list
    """
    stops = ["and", "or", "of", "the", "to"]
    return [word for word in text if word not in stops]

def remove_ordinal_suffix(text):
    """
    Removes ordinal suffix from a string

    :param text: Date to clean
    :type text: list
    :return: Cleaned string without ordinal suffix
    :rtype: list
    """
    while "st" in text:
        text.remove("st")
    while "rd" in text:
        text.remove("rd")
    while "nd" in text:
        text.remove("nd")
    while "th" in text:
        text.remove("th")

def remove_punct(text, dot=False, replace=""):
    """
    Remove the punctuation from the string
    :param text: Words of the date to clean
    :type text: str
    :param dot: Boolean if dots must be taken into account of not
    :type dot: bool
    :param replace: Character by which punctuation must be replaced, defaults to ""
    :type replace: str
    :return: Word without punctuation
    :type: str
    """
    punct = string.punctuation.replace("-", "")
    if not dot:
        punct = punct.replace(".", "")
    return "".join([char if char not in punct else replace for char in text])

def add_millennium_century(time, text, prepro):
    """
    Add a missing century/millennium keyword if there is a ordinal number without it

    :param time: Time dictionary with date metadata
    :type time: dict
    :param text: Original inputted string
    :type text: list
    :param prepro: Preprocessed string
    :type prepro: list
    """
    if "millennium" in text:
        prepro.append("millennium")
    elif "century" in text:
        prepro.append("century")
    else:
        corrected_text = spell_corrector(time["date_english"].split(), time["date_original_lang"])
        if "millennium" in corrected_text:
            prepro.append("millennium")
        else:
            prepro.append("century")

def check_ordinal_without_century(prepro, time):
    """
    Checks if there is an ordinal word without the "century" keyword.

    :param prepro: Preprocessed string to parse
    :type prepro: list
    :param time: Time dictionary with date metadata
    :type time: dict
    :return: Preprocessed string with added "century" keyword if its missing
    :rtype: str
    """
    #text = time["date_original"].split()
    text = time["date_english"].split()
    if len(prepro) == 1:
        if contain_numbers(prepro[0]) and extract_number_suffix(prepro[0]) in ["st", "nd", "rd", "th"]:
            add_millennium_century(time, text, prepro)
    elif len(prepro) == 2:
        if prepro[0].isnumeric() and prepro[1] in ["st", "nd", "rd", "th"]:
            add_millennium_century(time, text, prepro)
    if len(prepro) > 1:
        if contain_numbers(prepro[-1]) and extract_number_suffix(prepro[-1]) in ["st", "nd", "rd", "th"]:
            add_millennium_century(time, text, prepro)
    if len(prepro) > 2:
        if prepro[-2].isnumeric() and prepro[-1] in ["st", "nd", "rd", "th"]:
            add_millennium_century(time, text, prepro)
    return prepro

def spell_corrector(text, lang):
    """
    Corrects possible spelling mistakes in the string
    thanks to the SpellChecker API

    :param text: Date to clean
    :type text: list
    :param lang: Language of the string
    :type lang: str
    :return: String corrected from spelling mistakes
    :rtype: list
    """
    corrected = text
    keywords = ["century", "centuries", "c.", "millennium"]
    inter = [w for w in text if w in keywords]
    if inter:  # if contains keyword
        return corrected
    elif len(text) == 1 and contain_numbers(text[0]):  # if it's one word and contains a number
        return corrected
    elif len(text) == 2 and contain_numbers(text[1]) and text[0] == "ca.":
        return corrected
    for word in text:
        if word.isnumeric() and int(word) > 30:  # if there is a number present which is bigger than 30
            return corrected
    if lang in ["en", "pl", "ru", "uk", "tr", "es", "cs"]:
        spell = Speller(lang)
        corrected = [spell(word) if not contain_numbers(word) and word != "mid" else word for word in text]
    elif lang in ["fr", "de", "pt"]:
        spell = SpellChecker(language=lang)
        corrected = [spell.correction(word) if not contain_numbers(word) and word != "mid" else word for word in text]
    return corrected

def small_corrections(text):
    """
    Implements small corrections: "century" for "cen.", "centuries", "c."

    :param text: String to parse
    :type text: list
    :return: Cleaned string
    :rtype: list
    """
    new_text = []
    if "centuries" in text or "cen." in text:
        text = ["century" if w in ["centuries", "cen."] else w for w in text]
    for idx, word in enumerate(text):
        if word in ["c.", "c"] and idx != 0 and contain_numbers(text[idx - 1]) and extract_number(text[idx - 1]) < 22:
            new_text.append("century")
        elif contain_numbers(word):
            nbr = extract_number(word)
            suffix = extract_number_suffix(word)
            if nbr and suffix and suffix == retrieve_ordinal(nbr) + "c":
                new_text.append(str(nbr))
                new_text.append("century")
            else:
                new_text.append(word)
        else:
            new_text.append(word)
    return new_text

def check_comma_nbr(preprocessed):
    """
    Checks if there is a number with a comma in it (for ex: "1,000") and correct the word if present

    :param preprocessed: String to parse
    :type preprocessed: list
    :return: Cleaned string
    :rtype: list
    """
    new_text = []
    for word in preprocessed:
        if "," in word and contain_numbers(word):
            splitted = word.split(",")
            if len(splitted) == 2 and splitted[0].isnumeric() and splitted[1].isnumeric() and len(splitted[1]) == 3:
                new_text.append("".join(splitted))
            else:
                new_text.append(word)
        else:
            new_text.append(word)
    return new_text

def preprocess_text(text, time, correct_spelling=True, chronontology=False):
    """
    Preprocess the text in order to have a cleaned string. Steps
    - Split numeric and characters from the string
    - Remove the punctuations except dots
    - Convert roman numbers
    - Convert into lowercases

    :param text: Date to clean
    :type text: str
    :param time: Dictionary with date metadata
    :type time: dict
    :param correct_spelling: Boolean that indicates if the spelling must be corrected or not, defaults to True
    :type correct_spelling: bool
    :return: Cleaned string
    :rtype: list
    """
    if settings.__DEBUG__:
        log("Preprocessing string \"" + text + "\"")
    preprocessed = text
    if time["date_original_lang"] is None or time["date_original_lang"] == "en":
        printable = string.printable
        preprocessed = "".join([w if w in printable else " " for w in text])
    preprocessed = preprocessed.lower().split(" ")
    preprocessed = check_comma_nbr(preprocessed)
    preprocessed = " ".join([remove_punct(w, replace=" ") for w in preprocessed])
    preprocessed = preprocessed.split(" ")
    preprocessed = [w for w in preprocessed if w != ""]
    if not chronontology:
        preprocessed = check_convert_roman(preprocessed)
    if correct_spelling:
        preprocessed = spell_corrector(preprocessed, time["date_original_lang"])
    preprocessed = small_corrections(preprocessed)
    preprocessed = remove_stopwords(preprocessed)
    preprocessed = check_ordinal_without_century(preprocessed, time)
    if preprocessed and preprocessed[-1][-1] == ".":  # Not sure why this is needed
        preprocessed[-1] = preprocessed[-1][:-1]
    if settings.__DEBUG__:
        log(f"Preprocessed string is {preprocessed}")
    return preprocessed


import os
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
from sklearn.linear_model import LogisticRegression
from src.utils import Utils
from src.feature_generator import BuildFeatures
from src.dispatcher import Dispatcher
from src.metrics import Metrics
import argparse
import joblib
import json
import pprint
pp = pprint.PrettyPrinter(indent=4)

class Trainer:
    """Trains a model on the given dataset"""
    def __init__(self, config_path):
        self.config_path = config_path

        config = Utils().read_params(config_path)

        self.base = config["base"]
        self.estimator = config["base"]["estimator"]

        self.clean_data_path = config["clean_dataset"]["clean_folds_path"]
        self.model_dir = config["model_dir"]

        self.random_state = config["base"]["random_state"]

        self.scores_file = config["reports"]["scores_cv"]

    def train_and_evaluate(self):
        """Train the model and evaluate the model performance"""
        running_accuracy, running_f1, running_roc_auc, running_log_loss = [], [], [], []

        for i in range(1, 6):
            (accuracy, f1, roc_auc, log_loss_score) = self._train_one_fold(i - 1)

            running_accuracy.append(float(accuracy))
            running_f1.append(float(f1))
            running_roc_auc.append(float(roc_auc))
            running_log_loss.append(float(log_loss_score))

        scores = {
                "accuracy_score": sum(running_accuracy)/5,
                "f1_score": sum(running_f1)/5,
                "roc_auc_score": sum(running_roc_auc)/5,
                "log_loss_score": sum(running_log_loss)/5
            }

        print("-" * 50)
        print(f"  Model name: {self.estimator}")
        print(f"  Scores: \n")
        pp.pprint(scores)
        print("-" * 50)

        # Log Parameters and Scores for the cross validation
        with open(self.scores_file, "w") as f:
            json.dump(scores, f, indent=4)

    def _train_one_fold(self, fold_num):
        print(f"Training fold {fold_num} ...")
        xtrain_ft, ytrain, xvalid_ft, yvalid = BuildFeatures(self.config_path).build_features_train(fold_num)

        clf = Dispatcher(self.config_path).dispatch_model(self.estimator)

        clf.fit(xtrain_ft, ytrain)
        preds = clf.predict(xvalid_ft)
        pred_proba = clf.predict_proba(xvalid_ft)

        metrics_dict = Metrics(self.config_path)._eval_metrics(yvalid, preds, pred_proba)

        print("-" * 50)
        print(f"  Fold {fold_num} score: \n")
        pp.pprint(metrics_dict)
        print("-" * 50)

        return metrics_dict["accuracy"], metrics_dict["f1"], metrics_dict["roc_auc"], metrics_dict["log_loss"]

if __name__ == "__main__":
    args = argparse.ArgumentParser()
    args.add_argument("--config", default="params.yaml")
    parsed_args = args.parse_args()
    Trainer(config_path=parsed_args.config).train_and_evaluate()


from flask import Flask, render_template, redirect, url_for, request
from flask_restful import Api, Resource, reqparse
from flask_cors import CORS, cross_origin
import os
import json
import time
APP_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_PATH = os.path.join(APP_PATH, 'src/pages/')
app = Flask(__name__, template_folder=TEMPLATE_PATH)
cors = CORS(app)

# This file aims to download the user uploaded video to the
# appropriate local directory and update the user on any
# changes to result_update.json

@app.route('/home/results', methods = ['GET'])
def success():
    # Since we are looking for a file modification in the last 2 seconds,
    # delaying for 2 seconds ensures that we won't return results from a
    # previous 'Generate Results' run.
    time.sleep(2)
    file_dir=os.path.join(APP_PATH,'src/utils/AllResultsJSON/result_update.json')
    curr_time=time.time()
    file_mod_time=os.path.getmtime(file_dir)
    while(abs(curr_time-file_mod_time)>2):
        curr_time=time.time()
        file_mod_time=os.path.getmtime(file_dir)
    all_data=json.load(open(file_dir))
    # true->True, false->False... uppercase keywords undefined in JS.
    all_data[2]["beard"]=int(all_data[2]["beard"])
    all_data[3]["shades"]=int(all_data[3]["shades"])
    return {"models" : all_data}

@app.route('/home/upload', methods = ['POST'])
@cross_origin()
def upload_video():
    if request.method == 'POST':
        (request.files["file"]).save(os.path.join(APP_PATH,'backend/example_videos/target.mp4'))
        return "Successfully saved!"

if __name__ == '__main__':
   app.run(port=5000, debug = True)# 3000 , 5000


"""
Module used to store the SingleMovement serializer class, used to
serialize a movement.
"""
from budget.models.single_movement import SingleMovement
from budget.models.budget import Budget
from budget.models.budget_movement import BudgetMovement
from budget.serializers.movement_serializer import MovementSerializer
from rest_framework import serializers
from dotp_users.serializers.mixins import OwnerModelSerializerMixin

class SingleMovementSerializer(OwnerModelSerializerMixin):

    movement = MovementSerializer(required=True)
    budget = serializers.PrimaryKeyRelatedField(
        write_only=True,
        queryset=Budget.objects.all(),
        required=True,
    )

    class Meta:
        model = SingleMovement
        fields = [
            'movement',
            'budget',
        ]
        examples = {
            "budget": 1,
        }

    def create(self, validated_data):
        movement_data = validated_data.pop('movement', {})
        budget = validated_data.pop('budget', None)

        single_movement = super(SingleMovementSerializer, self).create(
            movement_data
        )
        category = single_movement.movement.category.unique_name
        direction = True if category == 'income' else False

        budget_movement_data = {
            'budget': budget,
            'movement': single_movement.movement,
            'direction': direction,
            'owner': single_movement.owner,
        }

        charge = BudgetMovement.objects.create(**budget_movement_data)

        return single_movement

    def update(self, instance, validated_data):
        movement_data = validated_data.pop('movement', {})
        budget = validated_data.pop('budget', None)

        b_mv = BudgetMovement.objects.filter(
            movement=instance.movement).first()

        if (budget is not None or
                movement_data.get('amount', None) is not None or
                movement_data.get('category', None) is not None):
            # Delete old BudgetMovement
            b_mv.delete()
            budget.refresh_from_db()

            # Update the movement instance to create new BudgetMovement
            for k, v in movement_data.items():
                setattr(instance, k, v)

            instance.save()

            # Create new BudgetMovement
            category = instance.movement.category.unique_name
            direction = True if category == 'income' else False

            budget_movement_data = {
                'budget': budget,
                'movement': instance.movement,
                'direction': direction,
            }

            charge = BudgetMovement.objects.create(**budget_movement_data)

        else:
            for k, v in movement_data.items():
                setattr(instance, k, v)

            instance.save()

        return instance


import seutils, os
from seutils import run_command, get_exitcode, Inode, split_mgm
import os.path as osp
logger = seutils.logger

IS_INSTALLED = None
def is_installed():
    """
    Checks whether xrdfs is on the path
    """
    global IS_INSTALLED
    if IS_INSTALLED is None: IS_INSTALLED = seutils.cmd_exists('ssh')
    return IS_INSTALLED

def _is_remote(path):
    return ':' in path

def _split_remote(path):
    return path.split(':', 1)

def _lsstatline_to_inode(l, server, parent_path):
    import datetime
    components = l.strip().split()
    isdir = components[0].startswith('d')
    timestamp = ' '.join(components[5:8])
    try:
        modtime = datetime.datetime.strptime(timestamp, '%b %d %H:%M')
    except ValueError:
        try:
            modtime = datetime.datetime.strptime(timestamp, '%b %d %Y')
        except ValueError:
            logger.error(
                'Tried multiple patterns but failed to get date from {0}'
                .format(timestamp)
                )
            raise
    size = int(components[4])
    path = server + ':' + osp.join(parent_path, ' '.join(components[8:]))
    return Inode(path, modtime, isdir, size)

def cp(src, dst, n_attempts=seutils.N_COPY_ATTEMPTS, create_parent_directory=True, verbose=True, force=False):
    cmd = [ 'scp', src, dst ]
    if verbose: cmd.insert(1, '-v')
    if create_parent_directory:
        parent_dir = osp.dirname(dst)
        if _is_remote(dst):
            mkdir(parent_dir)
        elif not osp.isdir(parent_dir):
            os.makedirs(osp.dirname(dst))
    run_command(cmd, n_attempts=n_attempts)

def listdir(directory, stat=False):
    server, path = _split_remote(directory)
    cmd = [ 'ssh', server, 'test -d {0} && ls {1} {0}'.format(path, '-l' if stat else '') ]
    output = run_command(cmd)
    contents = []
    for l in output:
        l = l.strip()
        if l.startswith('total '): continue
        if l.startswith('Warning'): continue
        if not len(l): continue
        if stat:
            if not(l.startswith('d') or l.startswith('-')): continue
            contents.append(_lsstatline_to_inode(l, server, path))
        else:
            contents.append(server + ':' + osp.join(path, l))
    return contents

def exists(path):
    server, path = _split_remote(path)
    return get_exitcode(['ssh', server, 'ls {0}'.format(path)]) == 0

def isfile(path):
    server, path = _split_remote(path)
    return get_exitcode(['ssh', server, 'test -f {0}'.format(path)]) == 0

def isdir(path):
    server, path = _split_remote(path)
    return get_exitcode(['ssh', server, 'test -d {0}'.format(path)]) == 0

def stat(fullpath):
    server, path = _split_remote(fullpath)
    cmd = [ 'ssh', server, 'ls -ld {0}'.format(path) ]
    output = run_command(cmd)
    contents = []
    for l in output:
        l = l.strip()
        if not len(l): continue
        if not(l.startswith('d') or l.startswith('-')): continue
        return _lsstatline_to_inode(l, server, path)

def is_file_or_dir(path):
    try:
        inode = stat(path)
        return 1 if inode.isdir else 2
    except Exception as e:
        logger.debug('Path {0} does not exist: {1}'.format(path, e))
        return 0

def mkdir(path):
    server, lpath = _split_remote(path)
    cmd = [ 'ssh', server, 'mkdir -p {0}'.format(lpath) ]
    run_command(cmd)

def rm(path, recursive=False):
    server, path = _split_remote(directory)
    cmd = [ 'ssh', server, 'rm {1} {0}'.format(path, '-rf' if recursive else '') ]
    run_command(cmd)

# _________________________________

def listdir_recursive(path):
    """
    Specific for ssh: Flat list of all files in a remote directory
    """
    server, lpath = _split_remote(path)
    cmd = [ 'ssh', server, 'find {0} -printf \'%y %s %A@ %p\n\''.format(lpath) ]
    logger.info('Gathering all inodes recursively in %s', path)
    output = run_command(cmd)
    contents = []
    for l in output:
        l = l.strip()
        if not len(l): continue
        if not(l.startswith('d') or l.startswith('f')): continue
        contents.append(_findline_to_inode(l, server))
    return contents

def _findline_to_inode(line, server):
    import datetime
    components = line.strip().split()
    path = server + ':' + ' '.join(components[3:])
    isdir = components[0] == 'd'
    size = int(components[1])
    modtime = datetime.datetime.fromtimestamp(float(components[2]))
    return Inode(path, modtime, isdir, size)


def reward_function(params):
    #imports

    import math

    #variables
    maxReward = 1e2
    minReward = 1e-3
    directionThresholdD = 10.0
    absSteeringThreshold = 30

    #car variables
    onTrack = params['all_wheels_on_track']
    distance_from_center = params['distance_from_center']
    track_width = params['track_width']
    steering = abs(params['steering_angle']) # Only need the absolute steering angle for calculations
    speed = params['speed']
    waypoints = params['waypoints']
    closest_waypoints = params['closest_waypoints']
    heading = params['heading']

    # negative exponential penalty
    reward = math.exp(-6 * distance_from_center)

    #rewards

    def onTrackReward(current_reward, onTrack):
        if not onTrack:
            current_reward = minReward
        else:
            current_reward = maxReward
        return current_reward

    def distance_from_center_reward(current_reward, track_width, distance_from_center):
        # Calculate 3 marks that are farther and father away from the center line
        marker_1 = 0.1 * track_width
        marker_2 = 0.25 * track_width
        marker_3 = 0.5 * track_width

        # Give higher reward if the car is closer to center line and vice versa
        if distance_from_center <= marker_1:
            current_reward *= 1.2
        elif distance_from_center <= marker_2:
            current_reward *= 0.8
        elif distance_from_center <= marker_3:
            current_reward += 0.5
        else:
            current_reward = minReward  # likely crashed/ close to off track

        return current_reward

    def straight_line_reward(current_reward, steering, speed):
        # Positive reward if the car is in a straight line going fast
        if abs(steering) < 0.1 and speed > 3:
            current_reward *= 1.2
        return current_reward

    def direction_reward(current_reward, waypoints, closest_waypoints, heading):

        '''
        Calculate the direction of the center line based on the closest waypoints
        '''

        next_point = waypoints[closest_waypoints[1]]
        prev_point = waypoints[closest_waypoints[0]]

        # Calculate the direction in radius, arctan2(dy, dx), the result is (-pi, pi) in radians
        direction = math.atan2(next_point[1] - prev_point[1], next_point[0] - prev_point[0])
        # Convert to degrees
        direction = math.degrees(direction)

        # Cacluate difference between track direction and car heading angle
        direction_diff = abs(direction - heading)

        # Penalize if the difference is too large
        if direction_diff > directionThresholdD:
            current_reward *= 0.5

        return current_reward

    def steering_reward(current_reward, steering):
        # Penalize reward if the car is steering too much (your action space will matter)
        if abs(steering) > absSteeringThreshold:
            current_reward += 0.8
        return current_reward

    def throttle_reward(current_reward, speed, steering):
        # Decrease throttle while steering
        if speed > 2.5 - (0.4 * abs(steering)):
            current_reward *= 0.8
        return current_reward

    #combine rewards
    reward = on_track_reward(reward, on_track)
    reward = distance_from_center_reward(reward, track_width, distance_from_center)
    reward = straight_line_reward(reward, steering, speed)
    reward = direction_reward(reward, waypoints, closest_waypoints, heading)
    reward = steering_reward(reward, steering)
    reward = throttle_reward(reward, speed, steering)

    return float(reward)


import os

import vk_api
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType
import random

def main():
    vk_session = vk_api.VkApi(
        token=TOKEN)
    longpoll = VkBotLongPoll(vk_session, '193402549')
    for event in longpoll.listen():
        if event.type == VkBotEventType.MESSAGE_NEW:
            print(event)
            print('Новое сообщение:')
            print('Для меня от:', event.obj.message['from_id'])
            print('Текст:', event.obj.message['text'])
            vk = vk_session.get_api()
            response = vk.users.get(user_id=event.obj.message['from_id'],
                                    fields="bdate, city")
            # print(response)
            vk.messages.send(user_id=event.obj.message['from_id'],
                             message=f"Привет, {response[0]['first_name']}",
                             random_id=random.randint(0, 2 ** 64))
            if 'city' in response[0]:
                vk.messages.send(user_id=event.obj.message['from_id'],
                                 message=f"Как поживает {response[0]['city']['title']}?",
                                 random_id=random.randint(0, 2 ** 64))

if __name__ == '__main__':
    TOKEN = str(os.environ.get("TOKEN"))
    main()