import pandas as pd
# 划分验证集，保存格式  text[\t]label
from sklearn.model_selection import train_test_split

# 自定义数据集
import os
import codecs
import csv

from paddlehub.dataset.base_nlp_dataset import BaseNLPDataset

def prepare_data():
    # 转换编码
    def re_encode(path):
        with open(path, 'r', encoding='GB2312', errors='ignore') as file:
            lines = file.readlines()
        with open(path, 'w', encoding='utf-8') as file:
            file.write(''.join(lines))

    #re_encode('data/test.csv')
    #re_encode('data/train.csv')

    # 读取数据
    train_labled = pd.read_csv('data/train.csv', engine ='python')
    test = pd.read_csv('data/test.csv', engine ='python')

    print(train_labled.shape)
    print(test.shape)
    print(train_labled.columns)

    train_labled.head(3)
    test.head(3)

    train_labled = train_labled[train_labled['情感倾向'].isin(['-1','0','1'])]
    train_labled['微博中文内容'].str.len().describe()

    train_labled = train_labled[['微博中文内容', '情感倾向']]
    train, valid = train_test_split(train_labled, test_size=0.2, random_state=2020)
    train.to_csv('./data/train.txt', index=False, header=False, sep='\t')
    valid.to_csv('./data/valid.txt', index=False, header=False, sep='\t')

class MyDataset(BaseNLPDataset):
    """DemoDataset"""
    def __init__(self):
        # 数据集存放位置
        self.dataset_dir = "./data"
        super(MyDataset, self).__init__(
            base_path=self.dataset_dir,
            train_file="train.txt",
            dev_file="valid.txt",
            test_file="valid.txt",
            train_file_with_header=False,
            dev_file_with_header=False,
            test_file_with_header=False,
            # 数据集类别集合
            label_list=["-1", "0", "1"])

def fine_tune():
    print("print my dataset")
    dataset = MyDataset()
    for e in dataset.get_train_examples()[:3]:
        print("{}\t{}\t{}".format(e.guid, e.text_a, e.label))

    import paddlehub as hub
    module = hub.Module(name="ernie", module_dir="./model")

    # 构建Reader
    print("vocab_path:", module.get_vocab_path())
    print("sp_model_path:", module.get_spm_path())
    print("word_dict_path:", module.get_word_dict_path())
    reader = hub.reader.ClassifyReader(
        dataset=dataset,
        vocab_path=module.get_vocab_path(),
        sp_model_path=module.get_spm_path(),
        word_dict_path=module.get_word_dict_path(),
        max_seq_len=256)

    # finetune策略1
    strategy = hub.L2SPFinetuneStrategy(
        learning_rate=1e-4,
        optimizer_name="adam",
        regularization_coeff=1e-3)

    # 运行配置
    config = hub.RunConfig(
        use_cuda=True,
        num_epoch=10,
        batch_size=32,
        checkpoint_dir="hub_finetune_ckpt0431",
        strategy=strategy)

    # Finetune Task
    inputs, outputs, program = module.context(
        trainable=True, max_seq_len=256)

    # Use "pooled_output" for classification tasks on an entire sentence.
    pooled_output = outputs["pooled_output"]

    feed_list = [
        inputs["input_ids"].name,
        inputs["position_ids"].name,
        inputs["segment_ids"].name,
        inputs["input_mask"].name,
    ]

    cls_task = hub.TextClassifierTask(
            data_reader=reader,
            feature=pooled_output,
            feed_list=feed_list,
            num_classes=dataset.num_labels,
            config=config,
            metrics_choices=["f1"])

    # finetune
    run_states = cls_task.finetune_and_eval()

if __name__ == "__main__":
    prepare_data()
    fine_tune()


import json
import random
import unittest

from cloudscope.config import settings
from cloudscope.results.metrics import *
from cloudscope.simulation.network import Message
from cloudscope.utils.serialize import JSONEncoder
from cloudscope.utils.statistics import OnlineVariance
from collections import namedtuple, defaultdict, Counter
from cloudscope.replica.consensus.raft import AppendEntries

##########################################################################
## Message Classes and Constants
##########################################################################

Greeting  = namedtuple('Greeting', 'salutation, introduction')
Heartbeat = namedtuple('Heartbeat', 'timestamp, status')
Replica   = namedtuple('MockReplica', 'id')

def pack(msg, source='alpha', target='bravo', delay=None):
    """
    Helper method to pack a message for the message metric classes.
    """
    delay = delay or random.randint(5,100)
    return Message(source, target, msg, delay)

##########################################################################
## Base Message Metric Tests
##########################################################################

class MessageMetricTests(unittest.TestCase):
    """
    Tests the message metric base class and common methods.
    """

    def test_interface(self):
        """
        Assert message metric interface
        """

        # Must have a deserialize class method
        with self.assertRaises(NotImplementedError):
            MessageMetric.deserialize({})

        # Interface for instance methods
        instance = MessageMetric()

        # Must have an update method
        with self.assertRaises(NotImplementedError):
            message = pack(Greeting("Hello There!", "My name is Jean."))
            instance.update(message)

        # Must have an serialize method
        with self.assertRaises(NotImplementedError):
            instance.serialize()

    def test_get_message_type(self):
        """
        Test the simple get message type on message metric
        """

        instance = MessageMetric()
        message = pack(Greeting("Gutentag!", "Mah nameh est Amy."))
        mtype = instance.get_message_type(message)

        self.assertEqual(mtype, Greeting.__name__)

    def test_none_message_type(self):
        """
        Test null message values on get message type
        """
        instance = MessageMetric()
        message = pack(None)
        mtype = instance.get_message_type(message)

        self.assertEqual(mtype, "None")

    def test_aggregate_heartbeats(self):
        """
        Ensure that heartbeats are aggregated in message metric
        """
        # Set aggregate heartbeats to True
        prev = settings.simulation.aggregate_heartbeats
        settings.simulation.aggregate_heartbeats = True

        term = 1
        leaderId = 'r8'
        prevLogIndex = 42
        prevLogTerm  = 1
        leaderCommit = 38

        instance = MessageMetric()
        simple_entries  = ['a', 'b', 'c', 'd']
        complex_entries = {'a': [1, 2, 3], 'b': [3,4,5], 'c':[5,7,8]}
        simple_no_entries  = []
        complex_no_entries =  {'a': None, 'b': None, 'c': None}

        # Helper function to make append entires messages
        mkmsg = lambda entries: pack(AppendEntries(term, leaderId, prevLogIndex, prevLogTerm, entries, leaderCommit))

        # Cases for testing
        cases = (
            (mkmsg(simple_entries), AppendEntries.__name__),
            (mkmsg(complex_entries), AppendEntries.__name__),
            (mkmsg(simple_no_entries), Heartbeat.__name__),
            (mkmsg(complex_no_entries), Heartbeat.__name__),
        )

        for msg, expected in cases:
            self.assertEqual(instance.get_message_type(msg), expected)

        # Return aggregate heartbeats to original state
        settings.simulation.aggregate_heartbeats = prev

    def test_no_aggregate_heartbeats(self):
        """
        Ensure that heartbeats are not aggregated in message metric
        """
        # Set aggregate heartbeats to True
        prev = settings.simulation.aggregate_heartbeats
        settings.simulation.aggregate_heartbeats = False

        term = 1
        leaderId = 'r8'
        prevLogIndex = 42
        prevLogTerm  = 1
        leaderCommit = 38

        instance = MessageMetric()
        simple_entries  = ['a', 'b', 'c', 'd']
        complex_entries = {'a': [1, 2, 3], 'b': [3,4,5], 'c':[5,7,8]}
        simple_no_entries  = []
        complex_no_entries =  {'a': None, 'b': None, 'c': None}

        # Helper function to make append entires messages
        mkmsg = lambda entries: pack(AppendEntries(term, leaderId, prevLogIndex, prevLogTerm, entries, leaderCommit))

        # Cases for testing
        cases = (
            (mkmsg(simple_entries), AppendEntries.__name__),
            (mkmsg(complex_entries), AppendEntries.__name__),
            (mkmsg(simple_no_entries), AppendEntries.__name__),
            (mkmsg(complex_no_entries), AppendEntries.__name__),
        )

        for msg, expected in cases:
            self.assertEqual(instance.get_message_type(msg), expected)

        # Return aggregate heartbeats to original state
        settings.simulation.aggregate_heartbeats = prev

##########################################################################
## Message Counter Tests
##########################################################################

class MessageCounterTests(unittest.TestCase):

    def test_update(self):
        """
        Test message counting on receipt of a message
        """
        a1 = Replica('a1')
        b3 = Replica('b3')

        counter = MessageCounter()
        self.assertEqual(counter.messages, {})
        self.assertEqual(counter.replicas, {})
        self.assertEqual(counter.received, {})

        # Add a greeting message sent from a1 to b3
        msg1 = pack(Greeting("Hola", "meet Joe"), a1, b3)
        counter.update(msg1, SENT)
        self.assertEqual(counter.messages, {SENT:{Greeting.__name__: 1}})
        self.assertEqual(counter.replicas, {'a1':{Greeting.__name__: 1}})
        self.assertEqual(counter.received, {})

        # Add a greeting message sent from b3 to a1
        msg2 = pack(Greeting("Hola", "meet Joe"), b3, a1)
        counter.update(msg2, SENT)
        self.assertEqual(counter.messages, {SENT:{Greeting.__name__: 2}})
        self.assertEqual(counter.replicas, {'a1':{Greeting.__name__: 1}, 'b3':{Greeting.__name__: 1}})
        self.assertEqual(counter.received, {})

        # Add the receipt of the message from a1 to b3
        counter.update(msg1, RECV)
        self.assertEqual(counter.messages, {SENT:{Greeting.__name__: 2}, RECV:{Greeting.__name__: 1}})
        self.assertEqual(counter.replicas, {'a1':{Greeting.__name__: 1}, 'b3':{Greeting.__name__: 1}})
        self.assertEqual(counter.received, {'b3':{Greeting.__name__: 1}})

        # Add the drop of the message from b3 to a1
        counter.update(msg2, DROP)
        self.assertEqual(counter.messages, {SENT:{Greeting.__name__: 2}, RECV:{Greeting.__name__: 1}, DROP:{Greeting.__name__: 1}})
        self.assertEqual(counter.replicas, {'a1':{Greeting.__name__: 1}, 'b3':{Greeting.__name__: 1}})
        self.assertEqual(counter.received, {'b3':{Greeting.__name__: 1}})

    def test_serialization(self):
        """
        Test message counter serialization and deserialization
        """
        a1 = Replica('a1')
        b3 = Replica('b3')

        counter = MessageCounter()
        msg1 = pack(Greeting("Hola", "meet Joe"), a1, b3)
        msg2 = pack(Greeting("Hola", "meet Joe"), b3, a1)
        counter.update(msg1, SENT)
        counter.update(msg2, SENT)
        counter.update(msg1, RECV)
        counter.update(msg2, DROP)

        # Serialize the Data
        data = json.loads(json.dumps(counter, cls=JSONEncoder))

        self.assertEqual(data, {
            "messages": {SENT:{Greeting.__name__: 2}, RECV:{Greeting.__name__: 1}, DROP:{Greeting.__name__: 1}},
            "replicas": {'a1':{Greeting.__name__: 1}, 'b3':{Greeting.__name__: 1}},
            "received": {'b3':{Greeting.__name__: 1}},
        })

        # Deserialize the data
        instance = MessageCounter.deserialize(data)
        self.assertEqual(instance.messages, {SENT:{Greeting.__name__: 2}, RECV:{Greeting.__name__: 1}, DROP:{Greeting.__name__: 1}})
        self.assertEqual(instance.replicas, {'a1':{Greeting.__name__: 1}, 'b3':{Greeting.__name__: 1}})
        self.assertEqual(instance.received, {'b3':{Greeting.__name__: 1}})

        for metric in (instance.messages, instance.replicas, instance.received):
            self.assertIsInstance(metric, defaultdict)
            for value in metric.values():
                self.assertIsInstance(value, Counter)

##########################################################################
## Latency Distribution Tests
##########################################################################

class LatencyDistributionTests(unittest.TestCase):

    def test_update(self):
        """
        Test latency distribution update on receipt of a message
        """

        c4 = Replica('c4')
        e1 = Replica('e1')

        dist = LatencyDistribution()
        self.assertEqual(dist.messages, {})

        # Add a greeting message sent from e1 to c4 with 10ms latency
        msg1 = pack(Greeting("Bonjour", "Larry"), e1, c4, 10)
        dist.update(msg1)
        self.assertEqual(dist.messages, {'e1': {'c4': {'Greeting': OnlineVariance([10])}}})

        # Add a greeting message sent from e1 to c4 with 20ms latency
        msg2 = pack(Greeting("Hello", "Larry"), e1, c4, 20)
        dist.update(msg2)
        self.assertEqual(dist.messages, {'e1': {'c4': {'Greeting': OnlineVariance([10, 20])}}})

        # Add a greeting message sent from c4 to e1 with 10ms latency
        msg3 = pack(Greeting("Hola", "James"), c4, e1, 10)
        dist.update(msg3)
        self.assertEqual(dist.messages, {'e1': {'c4': {'Greeting': OnlineVariance([10, 20])}}, 'c4': {'e1': {'Greeting': OnlineVariance([10])}}})

        # Add a greeting message sent from c4 to e1 with 30ms latency
        msg4 = pack(Greeting("Hola", "James"), c4, e1, 30)
        dist.update(msg4)
        self.assertEqual(dist.messages, {'e1': {'c4': {'Greeting': OnlineVariance([10, 20])}}, 'c4': {'e1': {'Greeting': OnlineVariance([10, 30])}}})

    def test_update_no_latency(self):
        """
        Test that samples increases even with messages of no latency.
        """
        # Replicas
        c4 = Replica('c4')
        e1 = Replica('e1')

        # Messages (at least two samples for stats)
        msg1 = pack(Greeting("Bonjour", "Larry"), e1, c4, 10)
        msg2 = pack(Greeting("Bonjour", "Larry"), e1, c4, 10)

        dist = LatencyDistribution()
        dist.update(msg1)
        dist.update(msg2)

        # Initialization verification
        self.assertIn(e1.id, dist.messages)
        self.assertIn(c4.id, dist.messages[e1.id])
        self.assertIn(Greeting.__name__, dist.messages[e1.id][c4.id])

        stats = dist.messages[e1.id][c4.id][Greeting.__name__]

        # Test the statistics prior to null delay
        self.assertEqual(stats.samples, 2)
        self.assertEqual(stats.total, 20)
        self.assertEqual(stats.squares, 200)
        self.assertEqual(stats.mean, 10)
        self.assertEqual(stats.std, 0.0)
        self.assertEqual(stats.var, 0.0)

        # Add the null latency message
        # Yep, this line is what we've done all this work for ...
        msg = Message(e1, c4, Greeting("Bonjour", "Larry"), None)
        dist.update(msg)

        # Test the statistics after null delay
        self.assertEqual(stats.samples, 3)
        self.assertEqual(stats.total, 20)
        self.assertEqual(stats.squares, 200)
        self.assertEqual(stats.mean, 6.666666666666667)
        self.assertEqual(stats.std, 5.773502691896258)
        self.assertEqual(stats.var, 33.333333333333336)

    def test_serialization(self):
        """
        Test latency distribution serialization and deserialization
        """

        c4 = Replica('c4')
        e1 = Replica('e1')

        msg1 = pack(Greeting("Bonjour", "Larry"), e1, c4, 10)
        msg2 = pack(Greeting("Hello", "Larry"), e1, c4, 20)
        msg3 = pack(Greeting("Hola", "James"), c4, e1, 10)
        msg4 = pack(Greeting("Hola", "James"), c4, e1, 30)

        dist = LatencyDistribution()
        for msg in (msg1, msg2, msg3, msg4):
            dist.update(msg)

        data = json.loads(json.dumps(dist, cls=JSONEncoder))
        newdist = LatencyDistribution.deserialize(data)
        self.assertEqual(newdist.messages, {'e1': {'c4': {'Greeting': OnlineVariance([10, 20])}}, 'c4': {'e1': {'Greeting': OnlineVariance([10, 30])}}})


from abc import ABC, abstractmethod
import requests
from src.vacancy import Vacancy
from datetime import datetime

class JobSite(ABC):

    @abstractmethod
    def get_vacancies_list(self):
        pass

    @abstractmethod
    def creation_objects(self, response):
        pass

class HeadHunter(JobSite):

    def __init__(self, params):
        self.url = "https://api.hh.ru/vacancies"
        self.params = params
        self.vacancies_list = []

    def get_vacancies_list(self) -> list:
        while self.params['page'] > 0:
            response = requests.get(self.url, params=self.params).json()['items']
            for vacancy in response:
                vacancy['resource'] = 'HeadHunter'
                self.vacancies_list.append(vacancy)
            self.params['page'] -= 1
        return self.vacancies_list

    @classmethod
    def creation_objects(cls, vacancies: list) -> list:
        objects_vacancy = []
        for vacancy in vacancies:
            all_data = vacancy
            resource = vacancy['resource']
            name = vacancy['name']
            city = vacancy['area']['name']
            url = vacancy['apply_alternate_url']
            published_at = vacancy['published_at'].split('+')[0]
            date_time = datetime.strptime(published_at, '%Y-%m-%dT%H:%M:%S')
            if vacancy['salary']:
                salary_from = vacancy['salary']['from']
                salary_to = vacancy['salary']['to']
                currency = vacancy['salary']['currency']
            else:
                salary_from = None
                salary_to = None
                currency = None
            if vacancy['snippet']['requirement']:
                requirement = vacancy['snippet']['requirement']
            else:
                requirement = "Не указаны"
            vac_object = Vacancy(all_data, resource, name, city, url, date_time,
                                 salary_from, salary_to, currency, requirement)
            objects_vacancy.append(vac_object)
        return objects_vacancy


# coding: utf-8

"""
    Operations

    The Operations API contains all the Azure Video Indexer APIs, like Upload video, Get insights and more, as well as authorization operations to get access tokens for calling the other operations. For Azure Resource Manager (ARM)-based accounts, some REST APIs like generating an access token, list of all accounts, and updating existing accounts can be found here.  # noqa: E501

    OpenAPI spec version: 1.0

    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

import pprint
import re  # noqa: F401

import six

class VideoInsightsStatistics(object):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    """
    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'correspondence_count': 'int',
        'speaker_longest_monolog': 'dict(str, int)',
        'speaker_number_of_fragments': 'dict(str, int)',
        'speaker_talk_to_listen_ratio': 'dict(str, float)',
        'speaker_word_count': 'dict(str, int)'
    }

    attribute_map = {
        'correspondence_count': 'correspondenceCount',
        'speaker_longest_monolog': 'speakerLongestMonolog',
        'speaker_number_of_fragments': 'speakerNumberOfFragments',
        'speaker_talk_to_listen_ratio': 'speakerTalkToListenRatio',
        'speaker_word_count': 'speakerWordCount'
    }

    def __init__(self, correspondence_count=None, speaker_longest_monolog=None, speaker_number_of_fragments=None, speaker_talk_to_listen_ratio=None, speaker_word_count=None):  # noqa: E501
        """VideoInsightsStatistics - a model defined in Swagger"""  # noqa: E501
        self._correspondence_count = None
        self._speaker_longest_monolog = None
        self._speaker_number_of_fragments = None
        self._speaker_talk_to_listen_ratio = None
        self._speaker_word_count = None
        self.discriminator = None
        if correspondence_count is not None:
            self.correspondence_count = correspondence_count
        if speaker_longest_monolog is not None:
            self.speaker_longest_monolog = speaker_longest_monolog
        if speaker_number_of_fragments is not None:
            self.speaker_number_of_fragments = speaker_number_of_fragments
        if speaker_talk_to_listen_ratio is not None:
            self.speaker_talk_to_listen_ratio = speaker_talk_to_listen_ratio
        if speaker_word_count is not None:
            self.speaker_word_count = speaker_word_count

    @property
    def correspondence_count(self):
        """Gets the correspondence_count of this VideoInsightsStatistics.  # noqa: E501

        :return: The correspondence_count of this VideoInsightsStatistics.  # noqa: E501
        :rtype: int
        """
        return self._correspondence_count

    @correspondence_count.setter
    def correspondence_count(self, correspondence_count):
        """Sets the correspondence_count of this VideoInsightsStatistics.

        :param correspondence_count: The correspondence_count of this VideoInsightsStatistics.  # noqa: E501
        :type: int
        """

        self._correspondence_count = correspondence_count

    @property
    def speaker_longest_monolog(self):
        """Gets the speaker_longest_monolog of this VideoInsightsStatistics.  # noqa: E501

        :return: The speaker_longest_monolog of this VideoInsightsStatistics.  # noqa: E501
        :rtype: dict(str, int)
        """
        return self._speaker_longest_monolog

    @speaker_longest_monolog.setter
    def speaker_longest_monolog(self, speaker_longest_monolog):
        """Sets the speaker_longest_monolog of this VideoInsightsStatistics.

        :param speaker_longest_monolog: The speaker_longest_monolog of this VideoInsightsStatistics.  # noqa: E501
        :type: dict(str, int)
        """

        self._speaker_longest_monolog = speaker_longest_monolog

    @property
    def speaker_number_of_fragments(self):
        """Gets the speaker_number_of_fragments of this VideoInsightsStatistics.  # noqa: E501

        :return: The speaker_number_of_fragments of this VideoInsightsStatistics.  # noqa: E501
        :rtype: dict(str, int)
        """
        return self._speaker_number_of_fragments

    @speaker_number_of_fragments.setter
    def speaker_number_of_fragments(self, speaker_number_of_fragments):
        """Sets the speaker_number_of_fragments of this VideoInsightsStatistics.

        :param speaker_number_of_fragments: The speaker_number_of_fragments of this VideoInsightsStatistics.  # noqa: E501
        :type: dict(str, int)
        """

        self._speaker_number_of_fragments = speaker_number_of_fragments

    @property
    def speaker_talk_to_listen_ratio(self):
        """Gets the speaker_talk_to_listen_ratio of this VideoInsightsStatistics.  # noqa: E501

        :return: The speaker_talk_to_listen_ratio of this VideoInsightsStatistics.  # noqa: E501
        :rtype: dict(str, float)
        """
        return self._speaker_talk_to_listen_ratio

    @speaker_talk_to_listen_ratio.setter
    def speaker_talk_to_listen_ratio(self, speaker_talk_to_listen_ratio):
        """Sets the speaker_talk_to_listen_ratio of this VideoInsightsStatistics.

        :param speaker_talk_to_listen_ratio: The speaker_talk_to_listen_ratio of this VideoInsightsStatistics.  # noqa: E501
        :type: dict(str, float)
        """

        self._speaker_talk_to_listen_ratio = speaker_talk_to_listen_ratio

    @property
    def speaker_word_count(self):
        """Gets the speaker_word_count of this VideoInsightsStatistics.  # noqa: E501

        :return: The speaker_word_count of this VideoInsightsStatistics.  # noqa: E501
        :rtype: dict(str, int)
        """
        return self._speaker_word_count

    @speaker_word_count.setter
    def speaker_word_count(self, speaker_word_count):
        """Sets the speaker_word_count of this VideoInsightsStatistics.

        :param speaker_word_count: The speaker_word_count of this VideoInsightsStatistics.  # noqa: E501
        :type: dict(str, int)
        """

        self._speaker_word_count = speaker_word_count

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value
        if issubclass(VideoInsightsStatistics, dict):
            for key, value in self.items():
                result[key] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, VideoInsightsStatistics):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        return not self == other


import glob
import joblib

def create_metadata():
    result = {}
    for i, path in enumerate(sorted(glob.glob("images/*.jpg"))):
        result[i] = path
    joblib.dump(result, "metadata.job.xz", compress=3)

if __name__ == "__main__":
    create_metadata()


# Criando o banco de Dados
import tkinter as tk
import sqlite3
import pandas as pd

# Conexão com o banco de dados
conexao = sqlite3.connect('clientes.db')
con = conexao.cursor()

# Criando a tabela no banco
con.execute(''' CREATE TABLE clientes(
   nome text,
   sobrenome text,
   email text,
   telefone text
)''')
# Confirmando
conexao.commit()
# Fechar o banco de dados
conexao.close()


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import json
import subprocess

from string import maketrans

from PySide.QtGui import QApplication, QFileDialog, QSystemTrayIcon, QMenu, QIcon, QPixmap

class LastDirectory(object):
    LAST_DIRECTORY = 'last_directory'
    CONFIG_FILE    = 'config.json'

    @staticmethod
    def get():
        json_ = json.load(open(LastDirectory.CONFIG_FILE, mode='r+'))

        lastDir = json_[LastDirectory.LAST_DIRECTORY] if os.path.isdir(json_[LastDirectory.LAST_DIRECTORY]) else os.path.dirname(os.path.realpath(sys.argv[0]))

        if len(lastDir) == 0:
            raise SystemExit

        json_[LastDirectory.LAST_DIRECTORY] = lastDir
        with open(LastDirectory.CONFIG_FILE, 'w') as json_file:
            json.dump(json_, json_file, sort_keys=True, indent=4, separators=(',', ':'))

        return lastDir

    @staticmethod
    def set(file):
        json_ = json.load(open(LastDirectory.CONFIG_FILE, mode='r+'))

        lastDir = os.path.dirname(os.path.realpath(file))

        if len(lastDir) == 0:
            raise SystemExit

        json_[LastDirectory.LAST_DIRECTORY] = lastDir
        with open(LastDirectory.CONFIG_FILE, 'w') as json_file:
            json.dump(json_, json_file, sort_keys=True, indent=4, separators=(',', ':'))

def getFileNew():
    fileNames, fileFilters = QFileDialog.getOpenFileNames(dir=LastDirectory.get())
    if len(fileNames) != 0:
        LastDirectory.set(fileNames[0])

    full_ = ''
    for i in fileNames:
        full_ += i if fileNames[-1] == i else i + ';'

    global app
    clipboard = app.clipboard()
    clipboard.setText(str(full_).translate(maketrans('\\', '/')))

def getDirectoryNew():
    directory_ = QFileDialog.getExistingDirectory()
    global app
    clipboard = app.clipboard()
    clipboard.setText(str(directory_).translate(maketrans('\\', '/')))

def getToolFileName(tool, comment):
    pyside_rcc, _ = QFileDialog.getOpenFileName(caption=u"Открыть {0}.exe, {1}".format(tool, comment), filter='*.exe')
    return pyside_rcc

def getTool(tool, comment):
    CONFIG_FILE = 'config.json'

    json_ = json.load(open(CONFIG_FILE, mode='r+'))

    toolFileName = json_[tool] if os.path.exists(json_[tool]) else getToolFileName(tool, comment)

    if len(toolFileName) == 0:
        raise SystemExit

    json_[tool] = toolFileName
    with open(CONFIG_FILE, 'w') as json_file:
        json.dump(json_, json_file, sort_keys=True, indent=4, separators=(',', ':'))

    return toolFileName

def processQrcFile():
    qrcFileName, _ = QFileDialog.getOpenFileName(caption=u'Выбери qrc файл', filter='*.qrc', dir=LastDirectory.get())
    LastDirectory.set(qrcFileName)

    pyFileName, _ = QFileDialog.getSaveFileName(caption=u'Сохрани py файл, незабудь "resources.qrc" -> "resources_rc.qrc"', filter='*.py', dir=LastDirectory.get())
    LastDirectory.set(pyFileName)

    subprocess.Popen([getTool('pyside_rcc', u'он где то тут: Python27/Lib/site-packages/PySide/pyside-rcc.exe'), qrcFileName, '-o', pyFileName])

def processUiFile():
    qrcFileName, _ = QFileDialog.getOpenFileName(caption=u'Выбери UI файл', filter='*.ui', dir=LastDirectory.get())
    LastDirectory.set(qrcFileName)

    pyFileName, _ = QFileDialog.getSaveFileName(caption=u'Сохрани py файл', filter='*.py', dir=LastDirectory.get())
    LastDirectory.set(pyFileName)

    subprocess.Popen([getTool('pyside_uic', u'он где то тут: Python27/Scripts/pyside-uic.exe'), qrcFileName, '-o', pyFileName])

def main():
    global app
    app = QApplication(sys.argv)

    tray_menu = QMenu()

    tray_menu.addAction(QIcon(QPixmap('data/file.png')), u'Получить пути файлов', getFileNew)
    tray_menu.addAction(QIcon(QPixmap('data/directory.png')), u'Получить путь директории', getDirectoryNew)
    tray_menu.addSeparator()
    tray_menu.addAction(QIcon(QPixmap('data/qrc.png')), u'Преобразовать .qrc в .py', processQrcFile)
    tray_menu.addAction(QIcon(QPixmap('data/ui.png')), u'Преозразовать .ui в .py', processUiFile)
    tray_menu.addSeparator()
    tray_menu.addAction(QIcon(QPixmap('data/close.png')), u'Выход', app.quit)

    tray = QSystemTrayIcon()
    tray.setIcon(QIcon(QPixmap('data//piggy.png')))
    tray.setContextMenu(tray_menu)
    tray.show()

    return app.exec_()

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time       : 2020/4/13 17:16
# @Author     : ShadowY
# @File       : get_juejin_info.py
# @Software   : PyCharm
# @Version    : 1.0
# @Description: 获取掘金后端信息
import requests
import json
import pymongo

header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36',
    'Referer': 'https://juejin.im/',
    'X-Agent': 'Juejin/Web',
    'Content-Type': 'application/json'
}
payload = {"operationName": "",
           "query": "",
           "variables": {
               "tags": [],
               "category": "5562b419e4b00c57d9b94ae2",
               "first": 20,
               "after": "",
               "order": "POPULAR"},
           "extensions": {
               "query": {
                   "id": "653b587c5c7c8a00ddf67fc66f989d42"
               }
           }
           }

def get_one_page(page_url, count=9999):
    """
    获取掘金一页信息
    :param page_url:
    :param count:
    :return:
    """
    infos = list()
    while True:
        res = requests.post(page_url, headers=header, data=json.dumps(payload))
        res.encoding = 'utf-8'
        html = res.text
        p_json = json.loads(html)['data']['articleFeed']['items']
        count -= 1
        if count == 0 or not p_json['pageInfo']['hasNextPage']:  # 判断是否结束
            break
        payload['variables']['after'] = p_json['pageInfo']['endCursor']
        datas = p_json['edges']
        for data in datas:
            info = {
                'comment': data['node']['commentsCount'],  # 评论数
                'title': data['node']['title'],  # 标题
                'likes': data['node']['likeCount'],  # 点赞数
                'update': data['node']['updatedAt'],  # 更新时间
                'username': data['node']['user']['username'],  # 用户名称
                'cont_url': data['node']['originalUrl'],  # 文章链接
            }
            print(info)
            infos.append(info)
    return infos

def write2mongodb(data):
    """
    写入mongodb数据库
    :param data: 列表数据
    :return:
    """
    db_client = pymongo.MongoClient(host='localhost', port=27017)
    db = db_client['tkh']
    jue = db['juejin']
    jue.insert_many(data)

if __name__ == '__main__':
    url = 'https://web-api.juejin.im/query'
    all_data = get_one_page(url, 20)
    write2mongodb(all_data)
    print('写入数据库成功')


import os
from utils import log
import requests
from pyquery import PyQuery as pq

"""
时光网TOP100爬虫

这个爬虫可以爬 10 个页面, 把所有 TOP100 电影都爬出来
并且加入了缓存页面功能
不用重复请求了(网络请求很 浪费时间)
这样做有两个好处
    1, 增加新内容(比如增加评论人数)的时候不用重复请求网络
    2, 出错的时候有原始数据对照

把封面给下载下来 并保存在image文件夹中
"""

class Model(object):
    def __repr__(self):
        name = self.__class__.__name__
        properties = ('{}=({})'.format(k, v) for k, v in self.__dict__.items())
        s = '\n<{} \n  {}>'.format(name, '\n  '.join(properties))
        return s

class Movie(Model):
    def __init__(self):
        self.name = ''
        self.score = 0
        self.quote = ''
        self.cover_url = ''
        self.ranking = 0

def cached_url(url):
    """
    缓存, 避免重复下载网页浪费时间
    """
    folder = 'cached'

    if '-' in url:
        filename = url.split('-', 1)[-1]
    else:
        filename = '1.html'

    path = os.path.join(folder, filename)
    if os.path.exists(path):
        with open(path, 'rb') as f:
            s = f.read()
        return s
    else:
        # 建立 cached 文件夹
        if not os.path.exists(folder):
            os.makedirs(folder)
        # 发送网络请求, 把结果写入到文件夹中
        r = requests.get(url)
        with open(path, 'wb') as f:
            f.write(r.content)
        return r.content

def movie_from_div(ranking, name, score, quote, cover_url):
    """
    从 div 里面获取到一个电影信息
        div1 = ranking[i]
        div2 = name[i]
        div3 = score[i]
        div4 = quote[i]
        div5 = cover_url[i]

    """
    e_ranking = pq(ranking)
    e_name = pq(name)
    e_score = pq(score)
    e_quote = pq(quote)
    e_cover = pq(cover_url)

    # 小作用域变量用单字符
    m = Movie()
    # 排名序号
    m.ranking = e_ranking('.number em').text()
    log('m.ranking', m.ranking)
    # 电影名字：前三名和后面标签不同
    if int(m.ranking) > 3:
        name = e_name('.c_blue').text()
        m.name = name.split(')', 1)[0]
    else:
        name = e_name('.c_fff').text()
        m.name = name.split(')', 1)[0]
    # point 评分分为两部分
    m.score = e_score('.total').text() + e_score('.total2').text()
    # 简介
    m.quote = e_quote('.mt3').text()
    # 图片链接
    m.cover_url = e_cover('img').attr('src')
    return m

def download_image(url, filename):
    r = requests.get(url)

    folder = 'image'
    if not os.path.exists(folder):
        os.makedirs(folder)
    path = os.path.join(folder, filename)

    with open(path, 'wb') as f:
        f.write(r.content)

def save_cover(movies):
    for m in movies:
        filename = '{}.jpg'.format(m.ranking)
        download_image(m.cover_url, filename)

def movies_from_url(url):
    page = cached_url(url)
    e = pq(page)

    ranking = e('.number')
    name = e('.mov_con')
    score = e('.mov_point')
    quote = e('.mt3')
    cover_url = e('img')

    movies = []
    for i in range(0, len(name)):
        # 调用 movie_from_div
        div1 = ranking[i]
        div2 = name[i]
        div3 = score[i]
        div4 = quote[i]
        div5 = cover_url[i]
        movie = movie_from_div(div1, div2, div3, div4, div5)
        movies.append(movie)
    return movies

def main():
    for i in range(1, 11):
        if i < 2:
            url = "http://www.mtime.com/top/movie/top100/"
        else:
            url = "http://www.mtime.com/top/movie/top100/index-{}.html".format(i)
        movies = movies_from_url(url)
        log('top100 movies', movies)
        save_cover(movies)

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
#coding=utf-8

import time
from functools import partial
from threading import Thread

def randoutput():
    while True:
        print(time.time())
        time.sleep(3)

th = Thread(target=randoutput,daemon=True)
th.start()

#cmd=''
#while cmd != 'exit':
#    cmd = input('sub>>> ')
#    print(cmd)
#

for cmd in iter(partial(input, "sub>> "), "quit"):
    print(cmd)


import pygame
import numpy as np

class GameOfLife:
    def __init__(self, width, height, cell_size, predictive_function):
        self.width = width
        self.height = height
        self.cell_size = cell_size
        self.grid = np.random.choice([0, 1], (height, width))
        self.predictive_function = predictive_function
        self.score = 0

    # Game of Life logic
    def step_logic(self):
        new_grid = np.zeros_like(self.grid)
        for i in range(self.height):
            for j in range(self.width):
                total = np.sum(self.grid[i - 1:i + 2, j - 1:j + 2]) - self.grid[i, j]
                if self.grid[i, j] and (total == 2 or total == 3):
                    new_grid[i, j] = 1
                elif not self.grid[i, j] and total == 3:
                    new_grid[i, j] = 1
        self.grid = new_grid

    def step(self):
        predicted_grid = self.predictive_function(self.grid)
        predicted_grid = np.array(predicted_grid)

        if predicted_grid.shape != self.grid.shape:
            raise ValueError("Predictive function returned grid of incorrect shape")

        self.step_logic()

        self.score += np.sum(self.grid == predicted_grid)

    def draw(self, surface):
        for y in range(self.height):
            for x in range(self.width):
                color = (255, 255, 255) if self.grid[y, x] else (0, 0, 0)
                pygame.draw.rect(surface, color, pygame.Rect(x * self.cell_size, y * self.cell_size, self.cell_size, self.cell_size))

def predictive_function_example(previous_grid):
    # Replace this with your predictive function.
    # For now, it just returns the input unchanged.
    return previous_grid

if __name__ == "__main__":
    pygame.init()
    WIDTH, HEIGHT = 500, 500
    CELL_SIZE = 50

    game_of_life = GameOfLife(WIDTH // CELL_SIZE, HEIGHT // CELL_SIZE, CELL_SIZE, predictive_function_example)

    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Conway's Game of Life")

    clock = pygame.time.Clock()

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_q):
                running = False

        game_of_life.step()
        screen.fill((0, 0, 0))
        game_of_life.draw(screen)
        pygame.display.flip()

        print(f"Current accuracy score: {game_of_life.score}")

        clock.tick(1)  # Update once per second

    pygame.quit()


from __future__ import print_function
import mock
import pytest
import sys

from sigopt.run_context import allow_state_update, RunContext

@pytest.mark.parametrize('new_state,old_state,expected', [
  ('completed', 'active', True),
  ('failed', 'active', True),
  ('completed', 'completed', False),
  ('failed', 'completed', True),
  ('completed', 'failed', False),
  ('failed', 'failed', False),
])
def test_allow_state_update(new_state, old_state, expected):
  assert allow_state_update(new_state, old_state) == expected

class TestLiveRunContext(object):
  def make_run_context(self):
    run_context = RunContext(
      connection=mock.Mock(),
      run=mock.Mock(assignments={"fixed1": 0, "fixed2": "test"}),
    )
    run_context._update_run = mock.Mock()
    return run_context

  @pytest.fixture
  def run_context(self):
    return self.make_run_context()

  @pytest.mark.parametrize('test_value', [
    12345,
    1.2345,
    'hello',
  ])
  def test_assignment_setitem(self, run_context, test_value):
    test_key = 'assignment_test_key'
    run_context.params[test_key] = test_value
    assert run_context.params[test_key] == test_value
    assert getattr(run_context.params, test_key) == test_value
    run_context._update_run.assert_called_once_with({'assignments': {test_key: test_value}})

  @pytest.mark.parametrize('test_value', [
    12345,
    1.2345,
    'hello',
  ])
  def test_assignment_setattr(self, run_context, test_value):
    test_key = 'assignment_test_key'
    setattr(run_context.params, test_key, test_value)
    assert run_context.params[test_key] == test_value
    assert getattr(run_context.params, test_key) == test_value
    run_context._update_run.assert_called_once_with({'assignments': {test_key: test_value}})

  def test_log_failure_method(self, run_context):
    return_value = run_context.log_failure()
    assert return_value is None
    run_context._update_run.assert_called_once_with({'state': 'failed'})

  @pytest.mark.parametrize('test_value', [
    12345,
    1.2345,
  ])
  def test_log_metadata_method_with_numbers(self, run_context, test_value):
    test_key = 'test_metadata_key'
    return_value = run_context.log_metadata(test_key, test_value)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'metadata': {test_key: test_value}})

  def test_log_metadata_method_with_null(self, run_context):
    test_key = 'test_metadata_key'
    return_value = run_context.log_metadata(test_key, None)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'metadata': {test_key: None}})

  @pytest.mark.parametrize('test_value', [
    'hello',
    [],
    {},
    object(),
  ])
  def test_log_metadata_method_stringifies_objects(self, run_context, test_value):
    test_key = 'test_metadata_key'
    return_value = run_context.log_metadata(test_key, test_value)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'metadata': {test_key: str(test_value)}})

  @pytest.mark.parametrize('test_value', [
    12345,
    1.2345,
  ])
  def test_log_metric_method_good_value(self, run_context, test_value):
    test_key = 'test_metric_key'
    return_value = run_context.log_metric(test_key, test_value)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'values': {
      test_key: {'value': test_value},
    }})

  @pytest.mark.parametrize('test_value', [
    None,
    'hello',
    [],
    {},
    object(),
  ])
  def test_log_metric_method_bad_value(self, run_context, test_value):
    test_key = 'test_metric_key'
    with pytest.raises(ValueError):
      run_context.log_metric(test_key, test_value)

  @pytest.mark.parametrize('test_stddev', [
    12345,
    1.2345,
  ])
  def test_log_metric_method_good_stddev(self, run_context, test_stddev):
    test_key = 'test_metric_key'
    test_value = 0
    return_value = run_context.log_metric(test_key, test_value, test_stddev)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'values': {
      test_key: {
        'value': test_value,
        'value_stddev': test_stddev,
      },
    }})

  @pytest.mark.parametrize('test_stddev', [
    'hello',
    [],
    {},
    object(),
  ])
  def test_log_metric_method_bad_stddev(self, run_context, test_stddev):
    test_key = 'test_metric_key'
    test_value = 0
    with pytest.raises(ValueError):
      run_context.log_metric(test_key, test_value, test_stddev)

  def test_log_dataset(self, run_context):
    dataset_name = 'dataset for testing'
    return_value = run_context.log_dataset(
      name=dataset_name,
    )
    assert return_value is None
    run_context._update_run.assert_called_once_with({'datasets': {
      dataset_name: {},
    }})

  def test_log_model(self, run_context):
    model_type = 'test type'
    return_value = run_context.log_model(type=model_type)
    assert return_value is None
    run_context._update_run.assert_called_once_with({'model': {'type': model_type}})


import logging

# HOST = "http://localhost"
HOST = "https://wiseagent.wise-xai.com"
# PORT = 8000
PORT = 443
WISEMQ_API_SERVER = HOST + ":" + str(PORT)

ERROR_CODES = [400, 401, 403, 406]

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


"""Test for the PostProc object."""

__author__ = "Thomas Bédrine"

import numpy as np
import pytest

from requests.exceptions import ReadTimeout
from ratelimit import limits, sleep_and_retry
from astropy.utils.data import download_file

from vip_hci.objects import PostProc, PPResult, Dataset
from vip_hci.fits import open_fits
from vip_hci.config import VLT_NACO

@sleep_and_retry
@limits(calls=1, period=1)
def download_resource(url):
    attempts = 5
    while attempts > 0:
        try:
            return download_file(url, cache=True)
        except ReadTimeout:
            attempts -= 1

    raise TimeoutError("Resource could not be accessed due to too many timeouts.")

def make_dataset_adi():
    """
    Download example FITS cube from github + prepare Dataset object.

    Returns
    -------
    dataset : HCIDataset

    Notes
    -----
    We use the helper function ``download_resource`` which handles the request
    and puts it to sleep for a defined duration if too many requests are done.
    They inherently call the Astropy's ``download_file`` function which uses caching,
    so the file is downloaded at most once per test run.

    """
    print("downloading data...")

    url_prefix = "https://github.com/vortex-exoplanet/VIP_extras/raw/master/datasets"

    f1 = download_resource(f"{url_prefix}/naco_betapic_cube_cen.fits")
    f2 = download_resource(f"{url_prefix}/naco_betapic_psf.fits")
    f3 = download_resource(f"{url_prefix}/naco_betapic_pa.fits")

    # load fits
    cube = open_fits(f1)
    angles = open_fits(f3).flatten()  # shape (61,1) -> (61,)
    psf = open_fits(f2)

    # create dataset object
    dataset = Dataset(cube=cube, angles=angles, psf=psf, px_scale=VLT_NACO["plsc"])

    dataset.normalize_psf(size=20, force_odd=False)

    # overwrite PSF for easy access
    dataset.psf = dataset.psfn

    return dataset

class TestParams:
    fwhm = None
    ncomp = None
    delta_rot = None

def test_postproc_object():
    """Create a PostProc object and test various actions on it."""
    t_postproc = PostProc(verbose=False)

    # Test if trying to update the dataset without any specified triggers AttributeError

    with pytest.raises(AttributeError) as excinfo:
        t_postproc._update_dataset()

    assert "No dataset was specified" in str(excinfo.value)

    # Test if trying to get parameters from non-existing results triggers AttributeError

    with pytest.raises(AttributeError) as excinfo:
        t_postproc.get_params_from_results(session_id=-1)

    assert "No results were saved yet" in str(excinfo.value)

    # Test if trying to get parameters for non-existing session triggers ValueError

    results = PPResult()
    t_postproc.results = results

    with pytest.raises(ValueError) as excinfo:
        t_postproc.get_params_from_results(session_id=-1)

    assert "ID is higher" in str(excinfo.value)

    # Test if trying to get parameters for incompatible algorithm triggers ValueError

    v_frame = np.zeros((10, 10))
    v_params = {"param1": None, "param2": None, "param3": 1.0}
    v_algo = "pca"

    results.register_session(frame=v_frame, algo_name=v_algo, params=v_params)

    t_postproc._algo_name = "median_sub"

    with pytest.raises(ValueError) as excinfo:
        t_postproc.get_params_from_results(session_id=-1)

    assert "does not match" in str(excinfo.value)

    # Test if non-overloaded run method triggers NotImplementedError

    with pytest.raises(NotImplementedError) as excinfo:
        t_postproc.run()

    assert excinfo.type == NotImplementedError

    # Test if the create_parameters_dict filters parameters correctly

    t_postproc.ncomp = 10
    t_postproc.fwhm = 4
    t_postproc.delta_rot = 0.5
    expected_class_params = {"ncomp": 10, "fwhm": 4, "delta_rot": 0.5}

    params_dict = t_postproc._create_parameters_dict(TestParams)

    assert expected_class_params == params_dict

    # Test if the update_dataset correctly adds a new dataset to self

    betapic = make_dataset_adi()

    t_postproc._update_dataset(dataset=betapic)

    assert t_postproc.dataset == betapic

    # Test if the explicit_dataset extracts correctly the params from dataset

    t_postproc._explicit_dataset()

    assert np.allclose(np.abs(t_postproc.cube), np.abs(betapic.cube), atol=1e-2)
    assert t_postproc.fwhm == betapic.fwhm
    assert np.allclose(np.abs(t_postproc.angle_list), np.abs(betapic.angles), atol=1e-2)
    assert np.allclose(np.abs(t_postproc.psf), np.abs(betapic.psfn), atol=1e-2)


from django.conf.urls import include, url
from django.views.decorators.csrf import csrf_exempt

from rest_framework.routers import DefaultRouter
from rest_framework.authtoken.views import obtain_auth_token

from .views import CircleViewSet, UserViewSet, RestaurantViewSet, ReviewViewSet, FoodieViewSet, PollViewSet, VoteViewSet, ProfileImageViewSet, CircleMembershipViewSet, CircleImageViewSet

router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'restaurants', RestaurantViewSet)
router.register(r'reviews', ReviewViewSet)
router.register(r'foodies', FoodieViewSet)
router.register(r'polls', PollViewSet)
router.register(r'votes', VoteViewSet)
router.register(r'upload_image',ProfileImageViewSet)
router.register(r'circles',CircleViewSet)
router.register(r'circle_memberships',CircleMembershipViewSet)
router.register(r'circle_image',CircleImageViewSet)

urlpatterns = router.urls

urlpatterns += [
    url(r'^obtain-auth-token/$', csrf_exempt(obtain_auth_token)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]


import time
import threading
from tkinter import Tk, Button, Label, mainloop
from playsound import playsound
# To do:
# - Add a progress bar or a visible clock
# - Add customize work period (seconds) and relax period (seconds)
# - Add customize start time
# - Add start/stop/reset button
# - Add sound effects
# Need 2 more tabs:
# - Add customize playlist
# - Add customize list for exercises

start_time = time.time()
wait_time = 5
rep_count = -1

def state_change_sound():
    playsound('relax.mp3')

def clock():
    global rep_count, start_time, wait_time
    seconds = int(time.time() - start_time)
    if seconds < wait_time:
        string = 'Wait time: ' + str(wait_time - seconds).zfill(2)
    else:
        seconds = (seconds - wait_time) % 60
        string = 'Rep Count: ' + str(rep_count) + ' '
    seconds_str = str(int(seconds)).zfill(2) if int(
        seconds) <= 44 else str(int(seconds) - 45).zfill(2)
    t = threading.Thread(target=state_change_sound)
    if seconds_str == '00' and rep_count != -1:
        t.start()
    if 'time' not in string:
        string += ('Work ' +
                   seconds_str) if int(seconds) <= 44 else ('Relax ' + seconds_str)

    if seconds == 0:
        rep_count += 1
    if rep_count >= 10:
        string = 'Done for Today'
    lbl.config(text=string)
    lbl.after(1000, clock)

def reset_sound():
    playsound('bell.mp3')

def reset():
    global rep_count, start_time
    rep_count = 0
    start_time = time.time()
    t = threading.Thread(target=reset_sound)
    t.start()

root = Tk()
root.title('Clock')
reset_button = Button(root, font=('calibri', 20),
                      text='Reset', command=reset)
reset_button.grid(column=0, row=1)

lbl = Label(root, font=('calibri', 100, 'bold'),
            background='purple',
            foreground='white')

lbl.grid(column=0, row=0)
clock()

mainloop()


from .detector import Detector
import dlib
import face_recognition
import face_recognition_models
import numpy as np
import cv2
import os
import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

TMP_DIR = "./../faceswap/tmp"

mean_face_x = np.array([
0.000213256, 0.0752622, 0.18113, 0.29077, 0.393397, 0.586856, 0.689483, 0.799124,
0.904991, 0.98004, 0.490127, 0.490127, 0.490127, 0.490127, 0.36688, 0.426036,
0.490127, 0.554217, 0.613373, 0.121737, 0.187122, 0.265825, 0.334606, 0.260918,
0.182743, 0.645647, 0.714428, 0.793132, 0.858516, 0.79751, 0.719335, 0.254149,
0.340985, 0.428858, 0.490127, 0.551395, 0.639268, 0.726104, 0.642159, 0.556721,
0.490127, 0.423532, 0.338094, 0.290379, 0.428096, 0.490127, 0.552157, 0.689874,
0.553364, 0.490127, 0.42689 ])

mean_face_y = np.array([
0.106454, 0.038915, 0.0187482, 0.0344891, 0.0773906, 0.0773906, 0.0344891,
0.0187482, 0.038915, 0.106454, 0.203352, 0.307009, 0.409805, 0.515625, 0.587326,
0.609345, 0.628106, 0.609345, 0.587326, 0.216423, 0.178758, 0.179852, 0.231733,
0.245099, 0.244077, 0.231733, 0.179852, 0.178758, 0.216423, 0.244077, 0.245099,
0.780233, 0.745405, 0.727388, 0.742578, 0.727388, 0.745405, 0.780233, 0.864805,
0.902192, 0.909281, 0.902192, 0.864805, 0.784792, 0.778746, 0.785343, 0.778746,
0.784792, 0.824182, 0.831803, 0.824182 ])

landmarks_2D = np.stack( [ mean_face_x, mean_face_y ], axis=1 )

def umeyama(src, dst, estimate_scale):
    """Estimate N-D similarity transformation with or without scaling.
    Parameters
    ----------
    src : (M, N) array
        Source coordinates.
    dst : (M, N) array
        Destination coordinates.
    estimate_scale : bool
        Whether to estimate scaling factor.
    Returns
    -------
    T : (N + 1, N + 1)
        The homogeneous similarity transformation matrix. The matrix contains
        NaN values only if the problem is not well-conditioned.
    References
    ----------
    .. [1] "Least-squares estimation of transformation parameters between two
            point patterns", Shinji Umeyama, PAMI 1991, DOI: 10.1109/34.88573
    """

    num = src.shape[0]
    dim = src.shape[1]

    # Compute mean of src and dst.
    src_mean = src.mean(axis=0)
    dst_mean = dst.mean(axis=0)

    # Subtract mean from src and dst.
    src_demean = src - src_mean
    dst_demean = dst - dst_mean

    # Eq. (38).
    A = np.dot(dst_demean.T, src_demean) / num

    # Eq. (39).
    d = np.ones((dim,), dtype=np.double)
    if np.linalg.det(A) < 0:
        d[dim - 1] = -1

    T = np.eye(dim + 1, dtype=np.double)

    U, S, V = np.linalg.svd(A)

    # Eq. (40) and (43).
    rank = np.linalg.matrix_rank(A)
    if rank == 0:
        return np.nan * T
    elif rank == dim - 1:
        if np.linalg.det(U) * np.linalg.det(V) > 0:
            T[:dim, :dim] = np.dot(U, V)
        else:
            s = d[dim - 1]
            d[dim - 1] = -1
            T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V))
            d[dim - 1] = s
    else:
        T[:dim, :dim] = np.dot(U, np.dot(np.diag(d), V.T))

    if estimate_scale:
        # Eq. (41) and (42).
        scale = 1.0 / src_demean.var(axis=0).sum() * np.dot(S, d)
    else:
        scale = 1.0

    T[:dim, dim] = dst_mean - scale * np.dot(T[:dim, :dim], src_mean.T)
    T[:dim, :dim] *= scale

    return T

class Faceswap(Detector):
    def __init__(self, blur_size=2, seamless_clone=False, mask_type="facehullandrect", erosion_kernel_size=None, **kwargs):
        super(Faceswap, self).__init__()
        self.build_pipeline_by_JSONFile("./faceswap_config.json")
        predictor_68_point_model = face_recognition_models.pose_predictor_model_location()
        self.pose_predictor = dlib.shape_predictor(predictor_68_point_model)
        self.erosion_kernel = None
        self.blur_size = blur_size
        self.seamless_clone = seamless_clone
        self.mask_type = mask_type.lower()
        self.video_capture = None
        self.all_faces = []

    def preprocess(self, frame):
        faces = []
        face_locations = face_recognition.face_locations(frame)
        landmarks = self._raw_face_landmarks(frame, face_locations)
        for ((y, right, bottom, x), landmarks) in zip(face_locations, landmarks):
            faces.append(DetectedFace(frame[y: bottom, x: right], x, right - x, y, bottom - y, landmarks))

        return faces

    def get_align_mat(self, face):
        return umeyama(np.array(face.landmarksAsXY()[17:]), landmarks_2D, True)[0:2]

    def _raw_face_landmarks(self, face_image, face_locations):
        face_locations = [self._css_to_rect(face_location) for face_location in face_locations]
        return [self.pose_predictor(face_image, face_location) for face_location in face_locations]

    def _css_to_rect(self, css):
        return dlib.rectangle(css[3], css[0], css[1], css[2])

    def get_image_mask(self, image, new_face, face_detected, mat, image_size):

        face_mask = np.zeros(image.shape,dtype=float)
        if 'rect' in self.mask_type:
            face_src = np.ones(new_face.shape,dtype=float)
            cv2.warpAffine( face_src, mat, image_size, face_mask, cv2.WARP_INVERSE_MAP, cv2.BORDER_TRANSPARENT )

        hull_mask = np.zeros(image.shape,dtype=float)
        if 'hull' in self.mask_type:
            hull = cv2.convexHull( np.array( face_detected.landmarksAsXY() ).reshape((-1,2)).astype(int) ).flatten().reshape( (-1,2) )
            cv2.fillConvexPoly( hull_mask,hull,(1,1,1) )

        if self.mask_type == 'rect':
            image_mask = face_mask
        elif self.mask_type == 'faceHull':
            image_mask = hull_mask
        else:
            image_mask = ((face_mask*hull_mask))

        if self.erosion_kernel is not None:
            image_mask = cv2.erode(image_mask,self.erosion_kernel,iterations = 1)

        if self.blur_size!=0:
            image_mask = cv2.blur(image_mask,(self.blur_size,self.blur_size))

        return image_mask

    def apply_new_face(self, image, new_face, image_mask, mat, image_size, size):
        base_image = np.copy( image )
        new_image = np.copy( image )

        cv2.warpAffine( new_face, mat, image_size, new_image, cv2.WARP_INVERSE_MAP, cv2.BORDER_TRANSPARENT )

        outImage = None
        if self.seamless_clone:
            masky,maskx = cv2.transform( np.array([ size/2,size/2 ]).reshape(1,1,2) ,cv2.invertAffineTransform(mat) ).reshape(2).astype(int)
            outimage = cv2.seamlessClone(new_image.astype(np.uint8),base_image.astype(np.uint8),(image_mask*255).astype(np.uint8),(masky,maskx) , cv2.NORMAL_CLONE )
        else:
            foreground = cv2.multiply(image_mask, new_image.astype(float))
            background = cv2.multiply(1.0 - image_mask, base_image.astype(float))
            outimage = cv2.add(foreground, background)

        return outimage

    def avg_color(self, old_face, new_face):
        w = old_face.shape[0]
        h = old_face.shape[1]
        old_face = old_face.astype(float)
        new_face = new_face.astype(float)

        rank = 5
        scale = 1.0 / rank

        for i in range(rank):
            new_face[i, i:w-i, :] = scale * i * new_face[i, i:w-i, :] + scale * (rank - i) * old_face[i, i:w-i, :]
            new_face[h-i-1, i:w-i, :] = scale * i * new_face[h-i-1, i:w-i, :] + scale * (rank - i) * old_face[h-i-1, i:w-i, :]
            new_face[i+1:h-i-1, i, :] = scale * i * new_face[i+1:h-i-1, i, :] + scale * (rank - i) * old_face[i+1:h-i-1, i, :]
            new_face[i+1:h-i-1, w-i-1, :] = scale * i * new_face[i+1:h-i-1, w-i-1, :] + scale * (rank - i) * old_face[i+1:h-i-1, w-i-1, :]
        diff = old_face[rank:h-rank-1, rank:w-rank-1, :] - new_face[rank:h-rank-1, rank:w-rank-1, :]
        avg_diff = np.sum(diff, axis=(0, 1)) / ((new_face.shape[0] - 2*rank) * (new_face.shape[1] - 2*rank))
        new_face[rank:h-rank-1, rank:w-rank-1, :] += avg_diff
        np.clip(new_face, 0.0, 255.0, out=new_face)
        return np.uint8(new_face)

    def process_of_video(self, video_file):
        i = 0
        size = 64
        if not os.path.exists(TMP_DIR):
            os.mkdir(TMP_DIR)
        videoCapture = cv2.VideoCapture(video_file)
        fps = videoCapture.get(cv2.CAP_PROP_FPS)
        videoWrite = cv2.VideoWriter(os.path.join(TMP_DIR, "origin_face.mp4"),
                                    cv2.VideoWriter_fourcc("m", "p", "4", "v"),
                                    fps, (size, size))
        success, frame = videoCapture.read()

        while success:
            faces = self.preprocess(frame)
            self.all_faces.append(faces)

            for face_detected in faces:
                mat = np.array(self.get_align_mat(face_detected)).reshape(2,3) * size
                face = cv2.warpAffine( frame, mat, (size,size) )
                videoWrite.write(np.uint8(face))
            success, frame = videoCapture.read()
            i += 1
            logger.info("detected face: processing {}".format(i))
        videoWrite.release()
        ret = self.detect_image(os.path.join(TMP_DIR, "origin_face.mp4"))
        self.video_capture = cv2.VideoCapture(os.path.join(TMP_DIR, str(ret) + ".avi"))

    def predict(self, frame, src_type):
        if src_type == "image":
            faces = self.preprocess(frame)
        elif src_type == "video":
            faces = self.all_faces.pop(0)
        size = 64
        image_size = frame.shape[1], frame.shape[0]
        if not os.path.exists(TMP_DIR):
            os.mkdir(TMP_DIR)

        for face_detected in faces:
            mat = np.array(self.get_align_mat(face_detected)).reshape(2,3) * size
            face = cv2.warpAffine( frame, mat, (size,size) )
            if src_type == "image":
                image_path = os.path.join(TMP_DIR, "origin_face.jpg")
                cv2.imwrite(image_path, face)
                ret = self.detect_image(image_path)
                if self.video_capture == None:
                    self.video_capture = cv2.VideoCapture(os.path.join(TMP_DIR, str(ret) + ".avi"))
                success, new_face = self.video_capture.read()
            elif src_type == "video":
                success, new_face = self.video_capture.read()
            new_face = self.avg_color(face, new_face)
            image_mask = self.get_image_mask(frame, new_face, face_detected, mat, image_size)
            frame = self.apply_new_face(frame, new_face, image_mask, mat, image_size, size)

        return np.uint8(frame)

class DetectedFace(object):
    def __init__(self, image, x, w, y, h, landmarks):
        self.image = image
        self.x = x
        self.w = w
        self.y = y
        self.h = h
        self.landmarks = landmarks

    def landmarksAsXY(self):
        return [(p.x, p.y) for p in self.landmarks.parts()]


from .common import Extractor, Message
from .. import text
import datetime

BASE_PATTERN = (
    r"(?:https?://)?"
    r"(danbooru|hijiribe|sonohara|safebooru)"
    r"\.donmai\.us"
)

class DanbooruExtractor(Extractor):
    """Base class for danbooru extractors"""
    basecategory = "booru"
    category = "danbooru"
    filename_fmt = "{category}_{id}_{md5}.{extension}"
    page_limit = 1000
    page_start = None
    per_page = 200

    def __init__(self, match):
        super().__init__(match)
        self.root = "https://{}.donmai.us".format(match.group(1))
        self.ugoira = self.config("ugoira", False)
        self.extended_metadata = self.config("metadata", False)

        username, api_key = self._get_auth_info()
        if username:
            self.log.debug("Using HTTP Basic Auth for user '%s'", username)
            self.session.auth = (username, api_key)

    def skip(self, num):
        pages = num // self.per_page
        if pages >= self.page_limit:
            pages = self.page_limit - 1
        self.page_start = pages + 1
        return pages * self.per_page

    def items(self):
        data = self.metadata()
        for post in self.posts():
            try:
                url = post["file_url"]
            except KeyError:
                continue

            text.nameext_from_url(url, post)
            if post["extension"] == "zip":
                if self.ugoira:
                    post["frames"] = self.request(
                        "{}/posts/{}.json?only=pixiv_ugoira_frame_data".format(
                            self.root, post["id"])
                    ).json()["pixiv_ugoira_frame_data"]["data"]
                    post["_http_adjust_extension"] = False
                else:
                    url = post["large_file_url"]
                    post["extension"] = "webm"

            if self.extended_metadata:
                template = (
                    "{}/posts/{}.json"
                    "?only=artist_commentary,children,notes,parent"
                )
                resp = self.request(template.format(self.root, post["id"]))
                post.update(resp.json())

            post.update(data)
            yield Message.Directory, post
            yield Message.Url, url, post

    def metadata(self):
        return ()

    def posts(self):
        return ()

    def _pagination(self, endpoint, params=None, pagenum=False):
        url = self.root + endpoint

        if params is None:
            params = {}
        params["limit"] = self.per_page
        params["page"] = self.page_start

        while True:
            posts = self.request(url, params=params).json()
            if "posts" in posts:
                posts = posts["posts"]
            yield from posts

            if len(posts) < self.per_page:
                return

            if pagenum:
                params["page"] += 1
            else:
                for post in reversed(posts):
                    if "id" in post:
                        params["page"] = "b{}".format(post["id"])
                        break
                else:
                    return

class DanbooruTagExtractor(DanbooruExtractor):
    """Extractor for danbooru posts from tag searches"""
    subcategory = "tag"
    directory_fmt = ("{category}", "{search_tags}")
    archive_fmt = "t_{search_tags}_{id}"
    pattern = BASE_PATTERN + r"/posts\?(?:[^&#]*&)*tags=([^&#]+)"
    test = (
        ("https://danbooru.donmai.us/posts?tags=bonocho", {
            "content": "b196fb9f1668109d7774a0a82efea3ffdda07746",
        }),
        # test page transitions
        ("https://danbooru.donmai.us/posts?tags=mushishi", {
            "count": ">= 300",
        }),
        ("https://hijiribe.donmai.us/posts?tags=bonocho"),
        ("https://sonohara.donmai.us/posts?tags=bonocho"),
        ("https://safebooru.donmai.us/posts?tags=bonocho"),
    )

    def __init__(self, match):
        super().__init__(match)
        self.tags = text.unquote(match.group(2).replace("+", " "))

    def metadata(self):
        return {"search_tags": self.tags}

    def posts(self):
        params = {"tags": self.tags}
        return self._pagination("/posts.json", params)

class DanbooruPoolExtractor(DanbooruExtractor):
    """Extractor for posts from danbooru pools"""
    subcategory = "pool"
    directory_fmt = ("{category}", "pool", "{pool[id]} {pool[name]}")
    archive_fmt = "p_{pool[id]}_{id}"
    pattern = BASE_PATTERN + r"/pools/(\d+)"
    test = ("https://danbooru.donmai.us/pools/7659", {
        "content": "b16bab12bea5f7ea9e0a836bf8045f280e113d99",
    })

    def __init__(self, match):
        super().__init__(match)
        self.pool_id = match.group(2)
        self.post_ids = ()

    def metadata(self):
        url = "{}/pools/{}.json".format(self.root, self.pool_id)
        pool = self.request(url).json()
        pool["name"] = pool["name"].replace("_", " ")
        self.post_ids = pool.pop("post_ids")
        return {"pool": pool}

    def posts(self):
        params = {"tags": "pool:" + self.pool_id}
        return self._pagination("/posts.json", params)

class DanbooruPostExtractor(DanbooruExtractor):
    """Extractor for single danbooru posts"""
    subcategory = "post"
    archive_fmt = "{id}"
    pattern = BASE_PATTERN + r"/posts/(\d+)"
    test = (
        ("https://danbooru.donmai.us/posts/294929", {
            "content": "5e255713cbf0a8e0801dc423563c34d896bb9229",
        }),
        ("https://danbooru.donmai.us/posts/3613024", {
            "pattern": r"https?://.+\.zip$",
            "options": (("ugoira", True),)
        })
    )

    def __init__(self, match):
        super().__init__(match)
        self.post_id = match.group(2)

    def posts(self):
        url = "{}/posts/{}.json".format(self.root, self.post_id)
        post = self.request(url).json()
        return (post["post"] if "post" in post else post,)

class DanbooruPopularExtractor(DanbooruExtractor):
    """Extractor for popular images from danbooru"""
    subcategory = "popular"
    directory_fmt = ("{category}", "popular", "{scale}", "{date}")
    archive_fmt = "P_{scale[0]}_{date}_{id}"
    pattern = BASE_PATTERN + r"/explore/posts/popular(?:\?([^#]*))?"
    test = (
        ("https://danbooru.donmai.us/explore/posts/popular"),
        (("https://danbooru.donmai.us/explore/posts/popular"
          "?date=2013-06-06&scale=week"), {
            "range": "1-120",
            "count": 120,
        }),
    )

    def __init__(self, match):
        super().__init__(match)
        self.params = text.parse_query(match.group(2))

    def metadata(self):
        scale = self.params.get("scale", "day")
        date = self.params.get("date") or datetime.date.today().isoformat()

        if scale == "week":
            date = datetime.date.fromisoformat(date)
            date = (date - datetime.timedelta(days=date.weekday())).isoformat()
        elif scale == "month":
            date = date[:-3]

        return {"date": date, "scale": scale}

    def posts(self):
        if self.page_start is None:
            self.page_start = 1
        return self._pagination(
            "/explore/posts/popular.json", self.params, True)


import csv
from datetime import datetime, date, timedelta

#funzione che va a scrivere i dati nel file csv match
def selectValueMatch(row, writer):
    if (row['match_num'] == '' or row['tourney_id'] ==''):
        print("MISS VALUE IN MATCH_NUM O IN TOURNEY_ID")
    row.update({'match_id': row['match_num']+ row['tourney_id']})
    writer.writerow(row)

#funzione che va a scrivere i dati nel file csv Tournament
def selectValueTournament(row, distinctValue, writer):
    row.update({'date_id': row['tourney_date']})
    KeySelected=row['tourney_id']

    #controllo che i duplicati su tourney_id (che non vengono inseriti) presentano valori diversi
    if KeySelected in distinctValue:
        rowSelected=distinctValue[KeySelected]
        for key in writer.fieldnames:
            if (row[key] != rowSelected[key]):
                print("Errore: torneo con id " + KeySelected + ' ha diversi valori su '+key+' '+row[key]+ ' '+rowSelected[key])

    #se invece la chiave non è presente, la vado a scrivere nel file e in distinctValue
    else:
        #salvo in distinctValue con key tourney_id e value un dizionario contenente tutti gli attributi in fieldnames
        rowTournament=dict()
        for attr in writer.fieldnames:
            rowTournament[attr]=row[attr]
        distinctValue[KeySelected]=rowTournament
        writer.writerow(row)

#funzione che va a scrivere i dati nel file csv Date
def selectValueData(row, distinctValue, writer):
    KeySelected=row['date_id']

    #controllo di non aver gia inserito il valore della chiave, qui non importa il controllo per gli errori:
    #gli altri campi derivano dal valore della chiave
    if KeySelected not in distinctValue:
        rowDate=dict()
        rowDate['date_id']=KeySelected

        #recupero giorno, mese, anno e quarter dalla data.
        #con strptime creo un object datetime partendo da una stringa e poi lo formatto con strftime
        rowDate['year'] = datetime.strptime(KeySelected, '%Y%m%d').strftime('%Y')
        rowDate['month']= datetime.strptime(KeySelected, '%Y%m%d').strftime('%B')
        rowDate['day']= datetime.strptime(KeySelected, '%Y%m%d').strftime('%A')
        rowDate['quarter']= 'Q'+ str(int((int(datetime.strptime(KeySelected, '%Y%m%d').strftime('%m')) +2)/3))
        #inserisco in distinctValue il dizionario con key date_id
        distinctValue[KeySelected]=rowDate
        writer.writerow(rowDate)

#funzione che va a scrivere i dati nel file csv Player.
#maleSet e femaleSet sono due set utilizzati dalla funzione per recuperare il sesso di un player in base al nome.
#La ricerca ha costo computazionale essendo il set hashato
def selectValuePlayer(row, distinctValue, writer, maleSet, femaleSet):

    players=['winner','loser']
    for player in players:
        #recupero l'id del player (winner o loser)
        KeySelected=row[player+'_id']

        #controllo se il player è già presente nel file di output e che non abbia valori diversi sugli attributi
        if KeySelected in distinctValue:
            rowSelected=distinctValue[KeySelected]
            for key in writer.fieldnames:
                if key == ('name')  and (row[player+'_'+key] != rowSelected[key]):
                    print("Errore: player con id " + KeySelected + ' ha diversi valori su '+key+' '+row[player+'_'+key]+ ' '+rowSelected[key])
                elif key == ('ioc') and (row[player+'_'+key] != rowSelected[key]):
                     print("Errore: player con id " + KeySelected + ' ha diversi valori su '+key+' '+row[player+'_'+key]+ ' '+rowSelected[key])
                elif key == ('hand')  and (row[player+'_'+key] != rowSelected[key]):
                     print("Errore: player con id " + KeySelected + ' ha diversi valori su '+key+' '+row[player+'_'+key]+ ' '+rowSelected[key])
                elif key == ('ht')  and (row[player+'_'+key] != rowSelected[key]):
                     print("Errore: player con id " + KeySelected + ' ha diversi valori su '+key+' '+row[player+'_'+key]+ ' '+rowSelected[key])

                #controllo che l'anno di nascita di row calcolato rispetto alla data del torneo combaci con quello già presente
                elif key == ('year_of_birth'):
                    newRowYear=annoNascita(row['tourney_date'],row[player+'_age'])
                    oldRowYear=rowSelected['year_of_birth']
                    if newRowYear!=oldRowYear and newRowYear!='':
                        print("Errore: player con id " + KeySelected + rowSelected['name']+' ha diversi valori su '+key+' nuovo = '+
                              str(newRowYear) +' vecchio = '+str(oldRowYear)+ ' con data torneo '+ row['tourney_date'])
                else:
                     continue
        else:
            #se invece non è ancora presente lo scrivo nel file e aggiorno distinctValue
            rowPlayer=dict()
            rowPlayer['player_id']=KeySelected
            rowPlayer['country_id'] = row[player+'_ioc']
            rowPlayer['name']= row[player+'_name']
            rowPlayer['hand']= row[player+'_hand']
            rowPlayer['ht']= row[player+'_ht']

            #controllo se il player con questo nome è nel set dei maschi o in quello delle femmine
            if (rowPlayer['name']) in maleSet:
                rowPlayer['sex']= 'male'

            elif (rowPlayer['name']) in femaleSet:
                rowPlayer['sex']= 'female'
            else:
                print('player con name '+rowPlayer['name']+' non ha sesso')
                rowPlayer['sex']= ''

            #calcolo l'anno di nascita del giocatore
            rowPlayer['year_of_birth']= annoNascita(row['tourney_date'],row[player+'_age'])

            #non inserisco row se il valore su year_of_birth è null.
            #inserirò il prossimo con anno di nascita!= null
            if rowPlayer['year_of_birth']=='':
                continue
            else:
                #inserisco il dizionario creato in distinctValue e lo vado a scrivere nel file
                distinctValue[KeySelected]=rowPlayer
                writer.writerow(rowPlayer)

#funzione che restituisce l'anno di nascita.
#a partire dall'età in float del player ad una certa data calcolo il giorno del compleanno del giocatore
#moltiplicando la parte decimale per 365 e sottraendo i giorni ottenuti dalla data del torneo.
#a questo punto estraggo l'anno di nascita dalla data del compleanno del giocatore
def annoNascita(dataTorneo, etaDuranteTorneo):

    #restituisce null se la data del torneo o l'età sono valori null
    if (dataTorneo=='' or etaDuranteTorneo==''):
        return ''

    else:
        annoTorneo = datetime.strptime(dataTorneo, '%Y%m%d').strftime('%Y')
        meseTorneo=datetime.strptime(dataTorneo, '%Y%m%d').strftime('%m')
        giornoTorneo=datetime.strptime(dataTorneo, '%Y%m%d').strftime('%d')
        dateTorneo = date(int(annoTorneo), int(meseTorneo), int(giornoTorneo))

        anniPlayer=int(float(etaDuranteTorneo))
        frazioneEtaPlayer=float(etaDuranteTorneo) - anniPlayer
        giorniTraCompleannoTorneo=int(frazioneEtaPlayer*365)

        dateBirthday=dateTorneo - timedelta(days=(giorniTraCompleannoTorneo) )
        result = dateBirthday.strftime("%Y")
        result=int(result) -anniPlayer

        return result

#funzione che creare il set di player a partire dal reader
#vengono concatenati nome e cog
def createSetPlayer(file):

    setPlayer=set()
    for row in file:
        value=''
        for attr in row:
            value=value+row[attr]+' '
        value=value[:-1]
        setPlayer.add(value)

    return setPlayer

if __name__ == '__main__':
    #percorsi file di input
    tennis_file='data/tennis_new.csv'
    male_file='data/male_new.csv'
    female_file='data/female_new.csv'

    #percorsi file di output
    match_file='table/match.csv'
    tournament_file='table/tournament.csv'
    player_file='table/player.csv'
    date_file='table/date.csv'

    #definisco i nomi degli attributi dei 5 file csv che saranno creati
    header_match = ['tourney_id', 'match_id', 'winner_id', 'loser_id', 'score', 'best_of', 'round', 'minutes', 'w_ace',
              'w_df', 'w_svpt', 'w_1stIn', 'w_1stWon', 'w_2ndWon', 'w_SvGms', 'w_bpSaved', 'w_bpFaced', 'l_ace',
              'l_df', 'l_svpt', 'l_1stIn', 'l_1stWon', 'l_2ndWon', 'l_SvGms', 'l_bpSaved', 'l_bpFaced', 'winner_rank',
              'winner_rank_points', 'loser_rank', 'loser_rank_points']
    header_tournament = ['tourney_id', 'date_id', 'tourney_name', 'surface', 'draw_size', 'tourney_level',
                   'tourney_spectators', 'tourney_revenue']
    header_player = ['player_id', 'country_id', 'name', 'sex', 'hand', 'ht', 'year_of_birth']
    header_date = ['date_id', 'day', 'month', 'year', 'quarter']
    header_country=['country_ioc','continent','language']

    #apro i file csv
    tennis= open(tennis_file, 'r')
    male= open(male_file, 'r')
    female= open(female_file, 'r')

    #utilizzo il DictReader per leggere il csv
    #ogni riga sarà un dizionario con chiave=attributo e valore=valore della riga su quell'attributo
    rtennis= csv.DictReader(tennis, delimiter=',')
    rMale= csv.DictReader(male, delimiter=',')
    rFemale= csv.DictReader(female, delimiter=',')

    #creo due set contenenti male e female
    maleSet=createSetPlayer(rMale)
    femaleSet=createSetPlayer(rFemale)

    #apro i 5 file csv dove andrò a scrivere i dati
    match= open(match_file, 'w', newline='')
    tournament= open(tournament_file, 'w', newline='')
    player= open(player_file, 'w', newline='')
    data = open(date_file, 'w', newline='')

    #utilizzo il DictWriter per scrivere i csv
    #in fieldnames va specificato l'header del csv in output
    #con extrasaction ignore vengono ignorati in scrittura gli attributi in più rispetto a fieldnames
    wmatch= csv.DictWriter(match, delimiter=',', fieldnames=header_match, extrasaction='ignore')
    wtournament = csv.DictWriter(tournament, delimiter=',', fieldnames=header_tournament, extrasaction='ignore')
    wplayer = csv.DictWriter(player, delimiter=',', fieldnames=header_player, extrasaction='ignore')
    wdate = csv.DictWriter(data, delimiter=',', fieldnames=header_date, extrasaction='ignore')

    #scrivo gli header nei csv
    writers = [wmatch, wtournament, wdate, wplayer]
    for w in writers:
        w.writeheader()

    #mantengo i valori distinti sulla primary key in dizioniari
    tournament_distinct=dict()
    player_distinct=dict()
    date_distinct=dict()
    country_distinct=dict()

    #itero su tennis e scrivo nei csv di output
    for row in rtennis:
        selectValueMatch(row, wmatch)
        selectValueTournament(row, tournament_distinct, wtournament)
        selectValuePlayer(row, player_distinct, wplayer, maleSet, femaleSet)
        selectValueData(row, date_distinct, wdate)

    #chiudo tutti file aperti in lettura
    tennis.close()
    male.close()
    female.close()

    #chiudo tutti file aperti in scrittura
    match.close()
    tournament.close()
    data.close()
    player.close()


from config.dbconfig import pg_config
import psycopg2

class CreditCardDAO:
    def __init__(self):

        connection_url = "dbname=%s user=%s host=%s password=%s" % (pg_config['dbname'],
                                                            pg_config['user'],
                                                            pg_config['host'],
                                                            pg_config['passwd'])
        self.conn = psycopg2._connect(connection_url)

    def getAllCards(self):
        cursor = self.conn.cursor()
        query = "select * from CreditCard;"
        cursor.execute(query)
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByClientId(self, cid):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s;"
        cursor.execute(query, (cid,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByNumber(self, ccnum):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where ccnum = %s;"
        cursor.execute(query, (ccnum,))
        result = cursor.fetchone()
        return result

    def getCardByExpirationDate(self, expdate):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where expdate = %s;"
        cursor.execute(query, (expdate,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByLimit(self, limit):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where limit = %s;"
        cursor.execute(query, (limit,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByCardVerificationValue(self,cvv):
        cursor =self.conn.cursor()
        query = "select * from CreditCard where cvv = %s;"
        cursor.execute(query,(cvv,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByClientAndCardNumber(self, cid, ccnum):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s and ccnum = %s;"
        cursor.execute(query, (cid, ccnum,))
        result = cursor.fetchone()
        return result

    def getCardByClientAndExpirationDate(self, cid, expdate) :
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s and expdate = %s;"
        cursor.execute(query, (cid, expdate,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByClientAndLimit(self, cid, limit) :
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s and limit = %s;"
        cursor.execute(query, (cid, limit,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByClientAndCardVerificationValue(self, cid, cvv):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s and cvv = %s;"
        cursor.execute(query, (cid, cvv,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByCardNumberAndExpirationDate(self, ccnum, expdate):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where ccnum = %s and expdate = %s;"
        cursor.execute(query, (ccnum, expdate,))
        result = cursor.fetchone()
        return result

    def getCardByCardNumberAndLimit(self, ccnum, limit):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where ccnum = %s and limit = %s;"
        cursor.execute(query, (ccnum, limit,))
        result = cursor.fetchone()
        return result

    def getCardByCardNumberAndCardVerificationValue(self, ccnum, cvv):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where ccnum = %s and cvv = %s;"
        cursor.execute(query, (ccnum, cvv,))
        result = cursor.fetchone()
        return result

    def getCardByExpirationDateAndLimit(self, expdate, limit):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where expdate = %s and limit = %s;"
        cursor.execute(query, (expdate, limit,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByExpirationDateAndCardVerificationValue(self, expdate, cvv):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where expdate = %s and cvv = %s;"
        cursor.execute(query, (expdate, cvv,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByLimitAndCardVerificationValue(self, limit, cvv):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where limit = %s and cvv = %s;"
        cursor.execute(query, (limit, cvv,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def getCardByClientAndCardNumberAndLimitAndCardVerificationValue(self, cid, ccnum, limit, cvv):
        cursor = self.conn.cursor()
        query = "select * from CreditCard where cid = %s and ccnum = %s and limit = %s and cvv = %s;"
        cursor.execute(query, (cid, ccnum, limit, cvv,))
        result = []
        for row in cursor:
            result.append(row)
        return result

    def insert(self, cid, ccnum, expdate, limit, cvv):
        cursor = self.conn.cursor()
        query = "insert into FirstAid(cid, ccnum, expdate, limit, cvv) values (%s, %s, %s, %s, %s) returning rid;"
        cursor.execute(query, (cid, ccnum, expdate, limit, cvv))


from django.shortcuts import render
from customer.models import Customer
from customer.forms import CustomerForm
from django.shortcuts import redirect
from product.models import Product
from useradmin.models import Useradmin
from product.forms import ProductForm
from buyproduct.models import Buyproduct
from buyproduct.forms import DeleteupdateForm
from useradmin.forms import UseradminForm

# Create your views here.
def admindash(request):
    if (request.method == "POST"):
        page = int(request.POST['page'])
        if ('prev' in request.POST):
            page = page - 1
        if ('next' in request.POST):
            page = page + 1
        tempOffSet = page - 1
        offset = tempOffSet * 7
        print(offset)
    else:
        offset = 0
        page = 1
    Ctotals=Customer.objects.all().count()
    Ptotals=Product.objects.all().count()
    Ototals=Buyproduct.objects.all().count()
    print(Ctotals)
    customers=Customer.objects.raw("select * from customer limit 7 offset % s", [offset])
    pageItem = len(customers)
    return render(request, "admin/admindash.html", {'Ctotals':Ctotals,'Ototals':Ototals,'Ptotals':Ptotals,'customers': customers, 'page': page, 'pageItem': pageItem})

def adminproduct(request):
    if (request.method == "POST"):
        page = int(request.POST['page'])
        if ('prev' in request.POST):
            page = page - 1
        if ('next' in request.POST):
            page = page + 1
        tempOffSet = page - 1
        offset = tempOffSet * 4
        print(offset)
    else:
        offset = 0
        page = 1

    products=Product.objects.raw('select * from product limit 4 offset % s', [offset])
    pageItem = len(products)
    return render(request,"admin/adminproduct.html",{'products':products, 'page': page, 'pageItem': pageItem})

def customer_delete(request,p_id):
    customer=Customer.objects.get(customer_id=p_id)
    customer.delete()
    return redirect ("/useradmin/admindash")

def billing(request):
    if (request.method == "POST"):
        page = int(request.POST['page'])
        if ('prev' in request.POST):
            page = page - 1
        if ('next' in request.POST):
            page = page + 1
        tempOffSet = page - 1
        offset = tempOffSet * 4
        print(offset)
    else:
        offset = 0
        page = 1

    bills=Buyproduct.objects.raw('select * from buyproduct limit 4 offset % s', [offset])
    pageItem = len(bills)
    return render(request,"admin/billings.html",{'bills':bills, 'page': page, 'pageItem': pageItem})

def updatecomplete(request,e_id):
    completeproduct=Buyproduct.objects.get(buyproduct_id=e_id)
    form=DeleteupdateForm(request.POST, instance=completeproduct)
    form.save()
    return redirect("/useradmin/billing")

def deletebill(request,d_id):
    deletebills=Buyproduct.objects.get(buyproduct_id=d_id)
    deletebills.delete()
    return redirect ("/useradmin/billing")

def userinfo(request):
    if(request.method=="POST"):
        page = int(request.POST['page'])
        if('prev' in request.POST):
            page= page-1
        if ('next' in request.POST):
             page=page+1
        tempOffSet = page - 1
        offset=tempOffSet*4
        print(offset)
    else:
        offset=0
        page=1
    users=Useradmin.objects.raw("select * from useradmin limit 4 offset % s",[offset])
    pageItem=len(users)
    return render(request,"admin/viewuser.html",{'users':users,'page':page,'pageItem':pageItem})

def adduser(request):
    if request.method=="POST":
        form=UseradminForm(request.POST)
        print(form)
        if form.is_valid():
            try:
                print("valid")
                form.save()
                return redirect("/useradmin/userinfo")
            except:
                print("validation failed")
    else:
        form=UseradminForm()
        print("invalid")
    return render(request, "admin/adduser.html",{'form':form})

def edituser(request,p_id):
    try:
       users=Useradmin.objects.get(id=p_id)
       print(users)
       return render(request, "admin/edituser.html", {'users':users})
    except:
       print("No Data Found")
    return redirect("/useradmin/userinfo")

def updateuser(request,p_id):
    user = Useradmin.objects.get(id=p_id)
    form = UseradminForm(request.POST, instance=user)
    if form.is_valid():
        try:
           form. save()
           return redirect("/useradmin/userinfo")

        except:
           print("validation failed")
    return render(request, "admin/edituser.html", {'users':user})

def deleteuser(request,p_id):
    try:
       user=Useradmin.objects.get(id=p_id)
       user.delete()
    except:
        print("No data Found")
    return redirect("/useradmin/userinfo")


#!/usr/bin/env python
#only for the predictions error, without comparisons (ground truth) and no publication on RVIZ

import rospy
from std_msgs.msg import String
from visualization_msgs.msg import MarkerArray
import torch
import time
import matplotlib.pyplot as plt
import threading
# from matplotlib.animation import FuncAnimation
# import matplotlib
# matplotlib.use('TkAgg')

import sys
sys.path.append('/home/bartonlab-user/workspace/src/human_motion_forecasting/scripts')
import os

from torch.utils.data import DataLoader
import torch.nn as nn
import numpy as np
import h5py
import torch.optim as optim

from utils.h36motion3d import Datasets
from model import AttModel
from utils.opt import Options
from utils import util
from utils import log

batch_size = 1
num_frames = 60
num_joints = 32
num_new_frames = 1  # Number of new frames to collect in each iteration

errors = []
error_cumulate = 0
fig, ax = plt.subplots()
line, = ax.plot([], [])

opt = Options().parse()

lr_now = opt.lr_now
start_epoch = 1
# opt.is_eval = True
print('>>> create models')
in_features = 66
d_model = opt.d_model
kernel_size = opt.kernel_size
net_pred = AttModel.AttModel(in_features=in_features, kernel_size=kernel_size, d_model=d_model,
                            num_stage=opt.num_stage, dct_n=opt.dct_n)
net_pred.cuda()
# model_path_len = '{}/ckpt_best.pth.tar'.format(opt.ckpt)
model_path_len = os.path.join('/home/bartonlab-user/workspace/src/human_motion_forecasting/scripts/checkpoint/HRI/main_h36m_3d_in50_out10_ks10_dctn20/ckpt_best.pth.tar')
# model_path_len = os.path.join('/home/bartonlab-user/workspace/src/azure_bodytracking/scripts/checkpoint/pretrained/h36m_3d_in50_out10_dctn20/ckpt_best.pth.tar')
print(">>> loading ckpt len from '{}'".format(model_path_len))
ckpt = torch.load(model_path_len)
start_epoch = ckpt['epoch'] + 1
err_best = ckpt['err']
lr_now = ckpt['lr']
net_pred.load_state_dict(ckpt['state_dict'])
print(">>> ckpt len loaded (epoch: {} | err: {})".format(ckpt['epoch'], ckpt['err']))

torch.cuda.empty_cache()

processed_data = torch.zeros(batch_size, num_frames, num_joints*3)
past_frames = torch.zeros(batch_size, num_frames - num_new_frames, num_joints*3)  # Store past frames

frame_count = 0
start_timestamp = time.time()
inference_time_mean = 0
actual_callbacks = 0

def run_model(net_pred, optimizer=None, is_train=0, input_data=None, epo=1, opt=None):
    net_pred.eval()
    titles = np.array(range(opt.output_n)) + 1
    m_p3d_h36 = np.zeros([opt.output_n])
    n = 0
    in_n = opt.input_n
    out_n = opt.output_n
    dim_used = np.array([6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 21, 22, 23, 24, 25,
                         26, 27, 28, 29, 30, 31, 32, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
                         46, 47, 51, 52, 53, 54, 55, 56, 57, 58, 59, 63, 64, 65, 66, 67, 68,
                         75, 76, 77, 78, 79, 80, 81, 82, 83, 87, 88, 89, 90, 91, 92])
    seq_in = opt.kernel_size
    # joints at same loc
    joint_to_ignore = np.array([16, 20, 23, 24, 28, 31])
    index_to_ignore = np.concatenate((joint_to_ignore * 3, joint_to_ignore * 3 + 1, joint_to_ignore * 3 + 2))
    joint_equal = np.array([13, 19, 22, 13, 27, 30])
    index_to_equal = np.concatenate((joint_equal * 3, joint_equal * 3 + 1, joint_equal * 3 + 2))

    itera = 3

    batch_size, seq_n, _ = input_data.shape

    n += batch_size
    bt = time.time()
    p3d_h36 = input_data.float().cuda()
    # print(p3d_h36.shape)
    # print(p3d_h36[0,0,:])
    # p3d_sup = p3d_h36.clone()[:, :, dim_used][:, -out_n - seq_in:].reshape(
    #     [-1, seq_in + out_n, len(dim_used) // 3, 3])
    p3d_src = p3d_h36.clone()[:, :, dim_used]
    # p3d_src = p3d_src.permute(1, 0, 2)  # seq * n * dim
    # p3d_src = p3d_src[:in_n]
    p3d_out_all = net_pred(p3d_src*1000, input_n=in_n, output_n=10, itera=itera)
    p3d_out_all = p3d_out_all*0.001

    p3d_out_all = p3d_out_all[:, seq_in:].transpose(1, 2).reshape([batch_size, 10 * itera, -1])[:, :out_n]

    p3d_out = p3d_h36.clone()[:, in_n:in_n + out_n]
    p3d_out[:, :, dim_used] = p3d_out_all
    p3d_out[:, :, index_to_ignore] = p3d_out[:, :, index_to_equal]

    #method in HRI
    # p3d_out = p3d_out.reshape([-1, out_n, 32, 3])
    # p3d_h36 = p3d_h36.reshape([-1, in_n + out_n, 32, 3])
    # mpjpe_p3d_h36 = torch.sum(torch.mean(torch.norm(p3d_h36[:, in_n:] - p3d_out, dim=3), dim=2), dim=0)

    #method in STS_GCN
    batch_pred=p3d_out.view(-1,out_n,32,3).contiguous().view(-1,3)
    batch_gt= p3d_h36[:, in_n:].view(-1, out_n,32,3).contiguous().view(-1,3)
    mpjpe_p3d_h36 =torch.mean(torch.norm(batch_gt-batch_pred,2,1))

    m_p3d_h36 += mpjpe_p3d_h36.cpu().data.numpy()

    ###

    ret = {}
    m_p3d_h36 = m_p3d_h36
    for j in range(out_n):
        ret["#{:d}".format(titles[j])] = m_p3d_h36[j]
    return ret

def body_tracking_callback(msg):

    global frame_count, start_timestamp, past_frames, error_cumulate, inference_time_mean, actual_callbacks

    marker_array = msg.markers
    coordinates = [[marker.pose.position.x, marker.pose.position.y, marker.pose.position.z]
                   for marker in marker_array]
    marker_tensor = torch.tensor(coordinates, dtype = torch.float32)

    # print(marker_tensor.shape)
    # print(marker_tensor)

    processed_data[:,frame_count] = marker_tensor.view(-1)

    frame_count +=1

    if frame_count == num_frames:

        if frame_count > num_new_frames:
            input_data = torch.cat((past_frames, processed_data[:,num_frames-num_new_frames:]), dim=1)
        else:
            input_data = processed_data

        input_data = processed_data.view(batch_size, num_frames, num_joints*3)

        elapsed_time = time.time() - start_timestamp
        print("Elapsed time between two callbacks:", elapsed_time)

        start_timestamp_inference = time.time()
        ret_test = run_model(net_pred, is_train=3, input_data=input_data, opt=opt)
        inference_time = time.time() - start_timestamp_inference
        print("Inference time:", inference_time)
        actual_callbacks += 1
        if actual_callbacks>1:
            inference_time_mean += inference_time
        print('testing error: {:.3f}'.format(ret_test['#10']))

        error_cumulate += ret_test['#10']
        errors.append(error_cumulate)
        update_plot()

        frame_count = num_frames - num_new_frames
        processed_data.zero_()

        if num_new_frames < num_frames:
            past_frames = input_data[:, num_new_frames:]

        start_timestamp = time.time()

        # allocated_memory = torch.cuda.memory_allocated(torch.device("cuda"))
        # print("Allocated GPU Memory:", allocated_memory)

def update_plot():
    line.set_data(range(len(errors)), errors)
    ax.relim()
    ax.autoscale_view()
    fig.canvas.draw_idle()

def main():
    global inference_time_mean, actual_callbacks
    rospy.init_node('subscriber_node', anonymous=True)
    rospy.Subscriber('body_tracking_data', MarkerArray, body_tracking_callback)
    # plt.ion()
    # plot_thread = threading.Thread(target=update_plot)
    # plot_thread.start()
    rospy.spin()
    # plot_thread.join()  # Wait for the plot thread to finish
    # plt.ioff()
    inference_time_mean = inference_time_mean/(actual_callbacks-1)
    print("mean Inference time:", inference_time_mean)
    plt.show()

if __name__ == '__main__':
    main()