import pytest

from stere.areas import Area, Areas

def test_areas_append_wrong_type():
    """Ensure a TypeError is raised when non-Area objects are appended
    to an Areas.
    """
    a = Areas()
    with pytest.raises(TypeError) as e:
        a.append('1')

    assert str(e.value) == (
        '1 is not an Area. Only Area objects can be inside Areas.'
    )

def test_areas_append():
    """Ensure Area objects can be appended to an Areas."""
    a = Areas()

    area = Area()
    a.append(area)

    assert 1 == len(a)

def test_areas_remove():
    """Ensure Areas.remove() behaves like list.remove()."""
    a = Areas()

    area = Area()
    a.append(area)
    a.remove(area)

    assert 0 == len(a)

def test_areas_len():
    """Ensure Areas reports length correctly."""
    a = Areas(['1', '2', '3'])
    assert 3 == len(a)


import datetime
from calendar import monthrange

def ValidacionFecha():
    date = input("Ingresa una fecha en numeros separadas en barras (Dia/Mes/Año ): ")

    dia,mes,año = date.split('/')

    valida = True
    try:
        datetime.datetime(int(año),int(mes),int(dia))
    except ValueError:
        valida = False

    if valida == True:
        print("{} es valida.".format(date))
        return date
    else:
        print("Dato ingreso invalido")
        exit

def CuantoParaFinDeMes():
    """
    Se calcula cuantos dias faltan para fin de mes
    """
    date = ValidacionFecha()
    formato = "%d/%m/%Y"
    dateobj = datetime.datetime.strptime(date, formato)
    yearnow = dateobj.year
    monthnow = dateobj.month
    daynow = dateobj.day
    days = monthrange(yearnow, monthnow)[1]
    try:
        daysleft = days - daynow
        print("{} restantes para fin de mes".format(daysleft))
    except ValueError:
        print("ERROR")

CuantoParaFinDeMes()


import os
import jsonpickle

def decide_folder_ignore(path):
    return path.endswith("_ignore")

def read_json_file(path, default_value={}):
    try:
        with open(path, encoding='utf-8') as f:
            return jsonpickle.decode(f.read())
    except (FileNotFoundError) as e:
        print(f"{path} - file not found or corrupted: {e.__class__}, {e}")
        return default_value

def write_json_file(path, data):
        try:
            txt = jsonpickle.encode(data, indent=4)
            with open(path, "w", encoding='utf-8') as f:
                f.write(txt)
                return True
        except (FileNotFoundError, TypeError) as e:
            print(f"{path} File not found or can't be written: {e.__class__}, {e}")
            return False


import os
from typing import List

from ariadne import (
    ObjectType,
    graphql_sync,
    load_schema_from_path,
    make_executable_schema,
    snake_case_fallback_resolvers,
)
from ariadne.constants import PLAYGROUND_HTML
from flask import jsonify, request

import api
from api import app, db, logger
from api.mutations import (
    resolve_assignRole,
    resolve_createMutation,
    resolve_createTodo,
    resolve_updateMutation,
    resolve_updateTodo,
)
from api.queries import (
    resolve_getQuery,
    resolve_getStudent,
    resolve_getTeacher,
    resolveGetTodo,
)

query = ObjectType("Query")

query.set_field("getUsers", resolve_getQuery)
query.set_field("getStudents", resolve_getStudent)
query.set_field("getTeachers", resolve_getTeacher)
query.set_field("getClasses", resolve_getQuery)
query.set_field("getSubjects", resolve_getQuery)
query.set_field("getTodos", resolveGetTodo)

mutation = ObjectType("Mutation")
mutation.set_field("createUser", resolve_createMutation)
mutation.set_field("createStudent", resolve_createMutation)
mutation.set_field("createTeacher", resolve_createMutation)
mutation.set_field("createClass", resolve_createMutation)
mutation.set_field("createSubject", resolve_createMutation)
mutation.set_field("createTodo", resolve_createTodo)

mutation.set_field("updateUser", resolve_updateMutation)
mutation.set_field("updateStudent", resolve_updateMutation)
mutation.set_field("updateTeacher", resolve_updateMutation)
mutation.set_field("updateTodo", resolve_updateTodo)

mutation.set_field("assignRole", resolve_assignRole)

def generate_schema() -> str:
    schema_str: str = ""
    base_folder: str = "./api/schema"
    schema_files: List[str] = [
        "Enums",
        "User",
        "Student",
        "Teacher",
        "Class",
        "Subject",
        "Todo",
        "typedefs",
        "schema",
    ]

    for file in schema_files:
        with open(os.path.join(base_folder, file + ".gql")) as f:
            schema_str += f.read() + "\n"

    return schema_str

type_defs: str = generate_schema()

schema = make_executable_schema(
    type_defs, [query, mutation], snake_case_fallback_resolvers
)

@app.route("/graphql", methods=["GET"])
def graphql_playground():
    return PLAYGROUND_HTML, 200

@app.route("/graphql", methods=["POST"])
def graphql_server():
    data = request.get_json()

    success, result = graphql_sync(schema, data, context_value=request, debug=app.debug)

    status_code = 200 if success else 400
    return jsonify(result), status_code


import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

# Cargar los datos desde el archivo CSV
data = pd.read_csv("datos.csv")

# Filtrar los datos hasta 2012/8/5
data = data[data["Año"] < 2012]
data = data[data["Mes"] < 8]
data = data[data["Dia"] <= 5]

# Obtener los valores de ozono
ozono = data["O3"].values

# Escalar los valores de ozono a un rango de [0, 1]
scaler = MinMaxScaler()
ozono = scaler.fit_transform(ozono.reshape(-1, 1))

# Preparar los datos para la red neuronal
X = []
y = []

# Utilizaremos los últimos 30 días para predecir los próximos 10 días
look_back = 30
look_forward = 10

for i in range(len(ozono) - look_back - look_forward):
    X.append(ozono[i : i + look_back])
    y.append(ozono[i + look_back : i + look_back + look_forward])

X = np.array(X)
y = np.array(y)

# Dividir los datos en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Crear el modelo de red neuronal
model = keras.Sequential()
model.add(keras.layers.LSTM(50, input_shape=(look_back, 1)))
model.add(keras.layers.Dense(look_forward))
model.compile(loss="mean_squared_error", optimizer="adam")

# Entrenar la red neuronal
model.fit(X_train, y_train, epochs=100, batch_size=32)

# Evaluar el modelo en datos de prueba
loss = model.evaluate(X_test, y_test)
print(f"Pérdida en datos de prueba: {loss}")

# Realizar predicciones para los próximos 10 días
last_30_days = ozono[-look_back:]
predicted_ozono = []

for _ in range(look_forward):
    next_day = model.predict(last_30_days.reshape(1, look_back, 1))
    predicted_ozono.append(next_day[0][0])
    last_30_days = np.roll(last_30_days, shift=-1)
    last_30_days[-1] = next_day[0][0]

# Invertir la escala de predicción a los valores originales
predicted_ozono = scaler.inverse_transform(np.array(predicted_ozono).reshape(-1, 1))

# Imprimir las predicciones
print(f"Predicciones para los próximos 10 días: {predicted_ozono}")
# Datos observados
observados = [17.88, 21.64, 25.03, 25.03, 23.25, 16.63, 10.1, 6.71, 4.2, 2.35]

# Sumar 10 a cada valor en los dos arrays
observados = np.array(observados) + 10
predicted_ozono = np.array(predicted_ozono) + 10

def mape(observed, predicted):
    return np.mean(np.abs((observed - predicted) / observed)) * 100

mapes = [mape(observados[i], predicted_ozono[i]) for i in range(len(observados))]

print("\nMAPE por línea:")
for i, mape_value in enumerate(mapes):
    print(f"Línea {i + 1}: {mape_value:.2f}%")


import math
import random
import collections

memo = {}
bonus_arr = [100, 500, 1000, 2500, 5000, 10000]

def targetSum(round):
    return math.floor(7 * round / 3)

def numbers(sum):
    num = []
    for i in range(5):
        num.append(random.randint(1, sum))
    return num

def bestSum(sum, num, memo, shortComb_list):
    if sum in memo: return memo[sum]
    if sum == 0: return []
    if sum < 0: return None
    shortComb = None
    for n in num:
        remain = sum - n
        result = bestSum(remain, num, memo, shortComb_list)
        if result != None:
            comb = [*result, n]
            if shortComb == None or len(shortComb) > len(comb): shortComb = comb #find shortest comb
            sum_of_comb = sum
            if sum_of_comb == totSum: #Find all correct combinations
                if len(shortComb_list) == 0: shortComb_list.append(comb)
                if len(comb) <= len(shortComb_list[0]):
                    if len(comb) < len(shortComb_list[0]): shortComb_list.clear()
                    shortComb_list.append(comb)
    if shortComb not in shortComb_list: memo[sum] = shortComb
    return shortComb

def filter(shortComb_list):
    new_shortComb_list = []
    for i in shortComb_list:
        if i not in new_shortComb_list:
            if new_shortComb_list != []:
                for j in new_shortComb_list:
                    if collections.Counter(i) != collections.Counter(j): new_shortComb_list.append(i)
                break
            new_shortComb_list.append(i)
    shortComb_list = new_shortComb_list
    return shortComb_list

def bonus(score):
    if score == None: score = 0
    if score >= bonus_arr[0] and score < bonus_arr[1]:
        print("Congrats! You made it past " + str(bonus_arr[0]) + " points. You get a " + str(score * 1.25) + " bonus.")
        score += score * 1.25
        del bonus_arr[0]
        return math.floor(score)
    return score

def gamePlay():
    global sum
    global score
    print('What is the shortest combination?')
    player_input = input("Sum: " + str(sum) + ' Choose numbers or \'0\' for None, and separate with \'+\': ' + str(num) + '   ')
    if player_input[-1] == '+': player_input = player_input[:-1]
    player_input = list(player_input.split('+'))
    player_input = [eval(i) for i in player_input]
    if shortComb_list == [] and player_input == [0]:
        score += 10
        print('Correct!!!')
        print('Score: ' + str(score))
        print('')
        return score
    for comb in shortComb_list:
        if collections.Counter(player_input) == collections.Counter(comb):
            score += sum
            print('Correct!!!')
            print('Score: ' + str(score))
            print('')
            return score
    if shortComb_list == []: return print('Wrong!!! The correct answer is: NONE')
    score -= sum
    print('Wrong!!! The correct answer is: ' + str(shortComb_list))
    print('Score: ' + str(score))
    print('')
    return score

if __name__ == "__main__":
    round = 1
    score = 0
    while round < 100:
        shortComb = []
        shortComb_list = []
        sum = targetSum(round)
        totSum = sum
        num = numbers(sum)
        memo.clear()
        if shortComb not in shortComb_list: bestSum(sum, num, memo, shortComb_list)
        shortComb_list = filter(shortComb_list)
        score = bonus(score)
        score = gamePlay()
        round += 1


import collections
import typing

def load():
    with open("inputs/14.txt") as f:
        return f.readlines()

def template():
    return load()[0].strip()

def rules():
    return {
        tuple(k.strip()): v.strip() for k, v in (row.split("->") for row in load()[2:])
    }

def count(steps: int):

    pairs = rules()
    cnt = collections.Counter(zip(template(), template()[1:]))

    for _ in range(steps):
        for key, n in tuple(cnt.items()):
            cnt[key] -= n
            m = pairs[key]
            f, s = key
            cnt[(f, m)] += n
            cnt[(m, s)] += n

    accumulated: typing.Counter[str] = collections.Counter()

    for (f, s), n in cnt.items():
        accumulated[f] += n
        accumulated[s] += n

    (_, most), *_, (_, least) = accumulated.most_common()

    # Don't undersant why i need to add one, but worked with
    # ex-data and work with real...
    return (most - least) // 2 + 1

if __name__ == "__main__":
    print("a:", count(10))
    print("b:", count(40))


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

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import click
import logging
import data
import preprocess
import utilities
from ngram_train import NgramTrain
import pandas as pd
from time import time
import evaluation_statistics
from ngram_test import NgramTest
from sklearn.model_selection import train_test_split
import gensim.downloader as api
from gensim.models import KeyedVectors

__author__ = "Pujaa Rajan"
__email__ = "pujaa.rajan@gmail.com"

@click.command()
@click.option('--output_file_path', is_flag=False, required=False, help = "output")
@click.option('--input_file_path', is_flag=False, required=False, help = "Input")
@click.option('--create_train_test_data', is_flag=False, required=False, help = "Training data")
@click.option('--training_data_file_path', is_flag=False, required=False, help = "Training data")
@click.option('--testing_data_file_path', is_flag=False, required=False, help = "Testing data")
@click.option('--cli', is_flag=True, required = False, help="Will run code using cli.")
@click.option('--run_ngram_train', is_flag=True, required=False, help='Will run train and test')
@click.option('--run_ngram_test', is_flag=True, required=False, help='Will run train and test')
def main(output_file_path, input_file_path, create_train_test_data, training_data_file_path, testing_data_file_path, run_ngram_train, run_ngram_test,  cli):
    """ Main function
    """

    utilities.logger()
    log = logging.getLogger('Enron_email_analysis.main')
    log.info('Starting to run main.py.')
    start = time()

    if create_train_test_data:
        log.info('Starting to create training and testing data')
        email_data = data.read_data(create_train_test_data) # Read in data from csv or s3 using file path
        email_content = email_data['content']
        training_emails, testing_emails = train_test_split(email_content, test_size=.2, train_size=.8, shuffle=True)
        log.info('Split data sent into training and testing')
        training_emails.to_csv(f'{input_file_path}/training_email_data.csv', header=['email_text'])
        log.info(f'Successfully created training emails csv: {input_file_path}/training_email_data.csv')
        testing_emails.to_csv(f'{input_file_path}/testing_email_data.csv', header=['email_text'])
        log.info(f'Successfully created testing emails csv: {input_file_path}/testing_email_data.csv')
        data.create_test_data(testing_emails, input_file_path)
        log.info(f'Successfully created fill in the blank test csv: {input_file_path}')

    if run_ngram_train:
        log.info("Starting to train ngram model")
        training_emails = pd.read_csv(training_data_file_path)
        preprocessed_training_emails = preprocess.PreprocessText(training_emails['email_text']).preprocessed_text
        NgramTrain(preprocessed_training_emails, input_file_path) # Done creating training data and
        log.info("Successfully finished training ngram model")

    if run_ngram_test:
        log.info("Starting to test ngram model")
        test_fill_in_the_blank = pd.read_csv(testing_data_file_path)
        ngram_test = NgramTest(test_fill_in_the_blank, output_file_path)
        evaluation_statistics.Evaluation(ngram_test)
        log.info("Successfully finished testing ngram model")

    if cli:

        log.info("Welcome to the Personalized Thesaurus.")
        log.info("ABOUT: This thesaurus recommends you the best word based on your previous emails and the"
                 "\nmost similar word.")
        log.info("Starting to reading in forward and backward probability pickle files")
        bigram_forward_probability = data.read_pickle_file(f'model_input_data/bigram_forward_probability.pkl')
        log.info("Successfully finished reading in 1/4 pickle files.")
        bigram_backward_probability = data.read_pickle_file(f'model_input_data/bigram_backward_probability.pkl')
        log.info("Successfully finished reading in 2/4 pickle files.")

        trigram_forward_probability = data.read_pickle_file(f'model_input_data/trigram_forward_probability.pkl')
        log.info("Successfully finished reading in 3/4 pickle files.")
        trigram_backward_probability = data.read_pickle_file(f'model_input_data/trigram_backward_probability.pkl')
        log.info("Successfully finished reading in 4/4 pickle files.")

        word_vectors = api.load("glove-wiki-gigaword-100")

        while True:
            log.info('Ready for user input')
            before_blank_tokens, after_blank_tokens, word_to_replace = utilities.take_input('cli')
            log.info(f'Before the word to replace: {before_blank_tokens}')
            log.info(f'After the word to replace: {after_blank_tokens}')
            after_predictions = data.predict_next_word(before_blank_tokens, bigram_forward_probability, trigram_forward_probability, 'forward')
            before_predictions = data.predict_next_word(after_blank_tokens, bigram_backward_probability, trigram_backward_probability, 'backward')
            merged_predictions = after_predictions+before_predictions
            word_embedding_output = data.get_similar_words(word_to_replace, word_vectors)
            print(f'Personalized Output:')
            for probability, word in merged_predictions:
                print(word + '\t' + str(probability))
            print(f'Similar Words:')
            for word, probability  in word_embedding_output:
                print(word + '\t' + str(probability))

    end = time()
    time_difference = end - start
    summary_statistics = open(f'summary_statistics.txt', 'a')
    summary_statistics.write(f'The program ran for: {time_difference}\n')
    summary_statistics.close()

if __name__ == "__main__":
    main()


"""
This is a tracker for cryptocurrencies. It only tracks the prices of 5 right
now, but I plan to add more.
"""

import requests
from datetime import datetime
import json

class ApiEndpointError(Exception):
    """
    ApiEndpointError class. This class is used to raise an error with
    connecting to the API endpoint.

    Attributes:
        errormsg: The error message to be displayed.
    """

    def __init__(self, errormsg):
        """
        Initializes the class with an error message.

        Args:
            errormsg: The error message to be displayed.

        Returns:
            Nothing.
        """

        self.errormsg = errormsg

    def __str__(self):
        """
        Converts the class to a string for printing purposes.

        Args:
            None.

        Returns:
            Nothing.
        """

        return repr(self.errormsg)

class CryptoTracker:
    """
    CryptoTracker class. This class is responsible for connecting to the API
    endpoint and recording data on various cryptocurrencies.

    Attributes:
        url: The API endpoint url.
        request: The object that holds get request data from the endpoint.
        bitcoin: Holds information about bitcoin.
        ethereum: Holds information about ethereum.
        ripple: Holds information about ripple.
        litecoin: Holds information about litecoin.
        tron: Holds information about tron.
    """

    def __init__(self):
        """
        Initializes the class with all its attributes.

        Args:
            None.

        Returns:
            Nothing.
        """

        self.url = 'https://api.coinmarketcap.com/v1/ticker'
        self.request = requests.get(self.url)
        self.bitcoin = None
        self.ethereum = None
        self.ripple = None
        self.litecoin = None
        self.tron = None

        self.set_crypto_data()

    def verify_endpoint_connection(self):
        """
        Verifies whether or not the endpoint was connected to successfully.

        Args:
            None.

        Returns:
            Returns true if the endpoint was successfully connected to, false
            otherwise.
        """

        return self.request.status_code == requests.codes.ok

    def get_api_data(self):
        """
        Gets the api data from the endpoint.

        Args:
            None.

        Returns:
            Returns the parsed json if the connection to the endpoint was
            successful, otherwise raises an error.

        Raises:
            ApiEndpointError: If the connection to the endpoing was
            unsuccessful.
        """

        if self.verify_endpoint_connection():
            return json.loads(self.request.text)
        else:
            raise ApiEndpointError('ERROR: Could not connect to API endpoint.')

    def set_crypto_data(self):
        """
        Sets class attributes with the appropriate crypto data.

        Args:
            None.

        Returns:
            Nothing.
        """

        for crypto in self.get_api_data():
            if crypto['id'] == 'bitcoin':
                self.bitcoin = crypto

            if crypto['id'] == 'ethereum':
                self.ethereum = crypto

            if crypto['id'] == 'ripple':
                self.ripple = crypto

            if crypto['id'] == 'litecoin':
                self.litecoin = crypto

            if crypto['id'] == 'tron':
                self.tron = crypto

    def write_data(self, filename):
        """
        Writes crypto data to a file.

        Args:
            filename: The name of the file to write to.

        Returns:
            Nothing.

        Raises:
            IOError: If the file could not be opened or written to.
        """

        try:
            with open(filename, 'w') as file_:
                file_.write('Time: ' + str(datetime.now()) + '\n')
                file_.write('Bitcoin price: ' +
                            str(self.bitcoin['price_usd']) + '\n')
                file_.write('Ethereum price: ' +
                            str(self.ethereum['price_usd']) + '\n')
                file_.write('Ripple price: ' +
                            str(self.ripple['price_usd']) + '\n')
                file_.write('Litecoin price: ' +
                            str(self.litecoin['price_usd']) + '\n')
                file_.write('Tron price: ' +
                            str(self.tron['price_usd']) + '\n')
        except IOError:
            raise IOError('ERROR: Could not open or write data.')


# Import KafkaProducer from Kafka library
from kafka import KafkaProducer
import configparser
import sys

# Reading config from kafka_conf.ini
config = configparser.ConfigParser()
config.read('kafka_conf.ini')

# Define server with port
bootstrap_servers = config['kafka_config']['bootstrap_server']

# Define topic name where the message will publish
topicName = config['kafka_config']['topic']

# Initialize producer variable
producer = KafkaProducer(bootstrap_servers = bootstrap_servers)

# Publish text in defined topic
while True:
    try:
        print("\nEnter message to send: ", end="")
        msg = input()
        ack = producer.send(topicName, bytes(msg, 'utf8'))

        # Print message
        print("********** Message Sent **********")
        metadata = ack.get()
        print("Topic: ", metadata.topic)
        print("Partiton: ", metadata.partition)
        print("Message: ", msg)
    except KeyboardInterrupt:
        print("Shutting down Producer !!!!")
        sys.exit()


import json

def shortify(name):
    return name[:25] + '...' if len(name) > 28 else name

fp_r = open('2019MeshTreeOriginal.json', 'r')
fp_w = open('2019MeshTree.json', 'w')

tree = json.load(fp_r)
tree_new = {'name': shortify(tree['name'])}
tree_depth = 5

curr, nxt = [], [(tree, tree_new)]

for i in range(tree_depth):
    curr, nxt = nxt, []
    for (old_node, new_node) in curr:
        if 'children' in old_node and i != tree_depth - 1:
            new_node['children'] = []
            children = old_node['children']
            children = sorted([c for c in children], key=lambda x: len(x['name']))
            for old_child_node in children[:30]:
                new_child_node = {'name': shortify(old_child_node['name'])}
                nxt.append((old_child_node, new_child_node))
                new_node['children'].append(new_child_node)
        else:
            new_node['value'] = 1

json.dump(tree_new, fp_w)

# import ipdb; ipdb.set_trace()


from absl.testing import parameterized
import numpy as np
from kws_streaming.layers import modes
from kws_streaming.layers import stream
from kws_streaming.layers import temporal_padding
from kws_streaming.layers import test_utils
from kws_streaming.layers.compat import tf
from kws_streaming.layers.compat import tf1
from kws_streaming.models import utils
from kws_streaming.train import test
tf1.disable_eager_execution()

# Toy example which require signal processing in time
class Sum(tf.keras.layers.Layer):
  """Applies Sum on time_dim."""

  def __init__(self, time_dim=1, **kwargs):
    super(Sum, self).__init__(**kwargs)
    self.time_dim = time_dim

  def call(self, inputs):
    return tf.keras.backend.sum(inputs, axis=self.time_dim)

  def get_config(self):
    config = {'time_dim': self.time_dim}
    base_config = super(Sum, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

def conv_model(flags, conv_cell, cnn_filters, cnn_kernel_size, cnn_act,
               cnn_dilation_rate, cnn_strides, cnn_use_bias, **kwargs):
  """Toy example of convolutional model with Stream wrapper.

  It can be used for speech enhancement.
  Args:
      flags: model and data settings
      conv_cell: cell for streaming, for example: tf.keras.layers.Conv1D
      cnn_filters: list of filters in conv layer
      cnn_kernel_size: list of kernel_size in conv layer
      cnn_act: list of activation functions in conv layer
      cnn_dilation_rate: list of dilation_rate in conv layer
      cnn_strides: list of strides in conv layer
      cnn_use_bias: list of use_bias in conv layer
      **kwargs: Additional kwargs passed on to conv_cell.
  Returns:
    Keras model

  Raises:
    ValueError: if any of input list has different length from any other
  """

  if not all(
      len(cnn_filters) == len(l) for l in [
          cnn_filters, cnn_kernel_size, cnn_act, cnn_dilation_rate, cnn_strides,
          cnn_use_bias
      ]):
    raise ValueError('all input lists have to be the same length')

  input_audio = tf.keras.layers.Input(
      shape=(flags.desired_samples,), batch_size=flags.batch_size)
  net = input_audio

  net = tf.keras.backend.expand_dims(net)

  for (filters, kernel_size, activation, dilation_rate, strides,
       use_bias) in zip(cnn_filters, cnn_kernel_size, cnn_act,
                        cnn_dilation_rate, cnn_strides, cnn_use_bias):

    net = stream.Stream(
        cell=conv_cell(
            filters=filters,
            kernel_size=kernel_size,
            activation=activation,
            dilation_rate=dilation_rate,
            strides=strides,
            use_bias=use_bias,
            padding='valid',
            **kwargs),
        use_one_step=False,
        pad_time_dim='causal')(net)

  return tf.keras.Model(input_audio, net)

def conv_model_no_stream_wrapper(flags, conv_cell, cnn_filters, cnn_kernel_size,
                                 cnn_act, cnn_dilation_rate, cnn_strides,
                                 cnn_use_bias, **kwargs):
  """Toy example of convolutional model.

  It has the same model topology as in conv_model() above, but without
  wrapping conv cell by Stream layer, so that all parameters set manually.
  Args:
      flags: model and data settings
      conv_cell: cell for streaming, for example: tf.keras.layers.Conv1D
      cnn_filters: list of filters in conv layer
      cnn_kernel_size: list of kernel_size in conv layer
      cnn_act: list of activation functions in conv layer
      cnn_dilation_rate: list of dilation_rate in conv layer
      cnn_strides: list of strides in conv layer
      cnn_use_bias: list of use_bias in conv layer
      **kwargs: Additional kwargs passed on to conv_cell.
  Returns:
    Keras model
  """

  if not all(
      len(cnn_filters) == len(l) for l in [
          cnn_filters, cnn_kernel_size, cnn_act, cnn_dilation_rate, cnn_strides,
          cnn_use_bias
      ]):
    raise ValueError('all input lists have to be the same length')

  input_audio = tf.keras.layers.Input(
      shape=(flags.desired_samples,), batch_size=flags.batch_size)
  net = input_audio

  net = tf.keras.backend.expand_dims(net)

  for filters, kernel_size, activation, dilation_rate, strides, use_bias in zip(
      cnn_filters, cnn_kernel_size,
      cnn_act, cnn_dilation_rate,
      cnn_strides, cnn_use_bias):

    ring_buffer_size_in_time_dim = max(
        dilation_rate * (kernel_size - 1) - (strides - 1), 0)
    net = stream.Stream(
        cell=tf.identity,
        ring_buffer_size_in_time_dim=ring_buffer_size_in_time_dim,
        use_one_step=False,
        pad_time_dim=None)(net)

    padding_size = ring_buffer_size_in_time_dim
    net = temporal_padding.TemporalPadding(
        padding='causal', padding_size=padding_size)(
            net)

    net = conv_cell(
        filters=filters,
        kernel_size=kernel_size,
        activation=activation,
        dilation_rate=dilation_rate,
        strides=strides,
        use_bias=use_bias,
        padding='valid',  # padding has to be valid!
        **kwargs)(net)

  return tf.keras.Model(input_audio, net)

def conv_model_keras_native(flags, conv_cell, cnn_filters, cnn_kernel_size,
                            cnn_act, cnn_dilation_rate, cnn_strides,
                            cnn_use_bias, **kwargs):
  """Toy example of convolutional model without any streaming components.

  It has the same model topology as in conv_model() above, but using only native
  Keras layers and no streaming components.
  Args:
      flags: model and data settings
      conv_cell: cell for streaming, for example: tf.keras.layers.Conv1D
      cnn_filters: list of filters in conv layer
      cnn_kernel_size: list of kernel_size in conv layer
      cnn_act: list of activation functions in conv layer
      cnn_dilation_rate: list of dilation_rate in conv layer
      cnn_strides: list of strides in conv layer
      cnn_use_bias: list of use_bias in conv layer
      **kwargs: Additional kwargs passed on to conv_cell.
  Returns:
    Keras model
  """

  if not all(
      len(cnn_filters) == len(l) for l in [
          cnn_filters, cnn_kernel_size, cnn_act, cnn_dilation_rate, cnn_strides,
          cnn_use_bias
      ]):
    raise ValueError('all input lists have to be the same length')

  input_audio = tf.keras.layers.Input(
      shape=(flags.desired_samples,), batch_size=flags.batch_size)
  net = input_audio

  net = tf.keras.backend.expand_dims(net)

  for filters, kernel_size, activation, dilation_rate, strides, use_bias in zip(
      cnn_filters, cnn_kernel_size,
      cnn_act, cnn_dilation_rate,
      cnn_strides, cnn_use_bias):

    # Note: This explicit padding is different from calling
    # conv_cell(..., padding='causal) directly when strides > 1. The latter
    # is suboptimal because it pads `strides - 1` extra zeros and hence ignores
    # the rightmost `strides - 1` valid samples. See the comments in
    # test_strided_conv_alignment() for a more concrete example.
    net = tf.keras.layers.ZeroPadding1D(
        [max(dilation_rate * (kernel_size - 1) - (strides - 1), 0), 0])(
            net)
    net = conv_cell(
        filters=filters,
        kernel_size=kernel_size,
        activation=activation,
        dilation_rate=dilation_rate,
        strides=strides,
        use_bias=use_bias,
        padding='valid',
        **kwargs)(net)

  return tf.keras.Model(input_audio, net)

class StreamTest(tf.test.TestCase, parameterized.TestCase):

  def setUp(self):
    super(StreamTest, self).setUp()
    test_utils.set_seed(123)

  def test_streaming_with_effective_tdim(self):
    time_size = 10
    feature_size = 3
    batch_size = 1

    time_dim = 1  # index of time dimensions
    ring_buffer_size_in_time_dim = 3  # effective size of aperture in time dim

    inputs = tf.keras.layers.Input(
        shape=(time_size, feature_size),
        batch_size=batch_size,
        name='inp_sequence')

    mode = modes.Modes.TRAINING

    # in streaming mode it will create a
    # ring buffer with time dim size ring_buffer_size_in_time_dim
    outputs = stream.Stream(
        cell=Sum(time_dim=time_dim),
        mode=mode,
        ring_buffer_size_in_time_dim=ring_buffer_size_in_time_dim)(inputs)
    model_train = tf.keras.Model(inputs, outputs)
    model_train.summary()

    mode = modes.Modes.STREAM_EXTERNAL_STATE_INFERENCE
    input_tensors = [
        tf.keras.layers.Input(
            shape=(
                1,  # time dim is size 1 in streaming mode
                feature_size,
            ),
            batch_size=batch_size,
            name='inp_stream')
    ]
    # convert non streaming model to streaming one
    model_stream = utils.convert_to_inference_model(model_train,
                                                    input_tensors, mode)
    model_stream.summary()

    # second input tostream model is a state, so we can use its shape
    input_state_np = np.zeros(model_stream.inputs[1].shape, dtype=np.float32)

    # input test data
    non_stream_input = np.random.randint(
        1, 10, size=(batch_size, time_size, feature_size))

    # run streaming inference
    # iterate over time dim sample by sample
    for i in range(input_state_np.shape[1]):
      input_stream_np = np.expand_dims(non_stream_input[0][i], 0)
      input_stream_np = np.expand_dims(input_stream_np, 1)
      input_stream_np = input_stream_np.astype(np.float32)
      output_stream_np, output_state_np = model_stream.predict(
          [input_stream_np, input_state_np])
      input_state_np = output_state_np  # update input state

      # emulate sliding window summation
      target = np.sum(
          non_stream_input[:, max(0, i - ring_buffer_size_in_time_dim):i + 1],
          axis=time_dim)
      self.assertAllEqual(target, output_stream_np)

    # validate name tag of model's state
    expected_str = 'ExternalState'
    self.assertAllEqual(
        expected_str,
        model_stream.inputs[1].name.split('/')[-1][:len(expected_str)])

  @parameterized.parameters('causal', 'same')
  def test_padding(self, padding):
    batch_size = 1
    time_dim = 3
    feature_dim = 3
    kernel_size = 3
    inputs = tf.keras.layers.Input(
        shape=(time_dim, feature_dim), batch_size=batch_size)

    # set it in train mode (in stream mode padding is not applied)
    net = stream.Stream(
        mode=modes.Modes.TRAINING,
        cell=tf.keras.layers.Lambda(lambda x: x),
        ring_buffer_size_in_time_dim=kernel_size,
        pad_time_dim=padding)(inputs)
    model = tf.keras.Model(inputs, net)

    test_utils.set_seed(1)
    input_signal = np.random.rand(batch_size, time_dim, feature_dim)
    outputs = model.predict(input_signal)
    self.assertAllEqual(outputs.shape,
                        [batch_size, time_dim + kernel_size - 1, feature_dim])

  def test_strided_conv_alignment(self):
    kernel_size = 4
    strides = 2
    inputs = tf.keras.layers.Input(shape=(None, 1))
    net = inputs
    net = stream.Stream(
        cell=tf.keras.layers.Conv1D(
            filters=1,
            kernel_size=kernel_size,
            strides=strides,
            padding='valid',
            kernel_initializer='ones'),
        use_one_step=False,
        pad_time_dim='causal')(
            net)
    model = tf.keras.Model(inputs=inputs, outputs=net)

    input_signal = np.arange(1, 5)  # [1, 2, 3, 4]
    # Sanity check for the test itself: We only care about the case when input
    # length is a multiple of strides. If not, streaming is not meaningful.
    assert len(input_signal) % strides == 0
    input_signal = input_signal[None, :, None]
    output_signal = model.predict(input_signal)
    outputs = output_signal[0, :, 0]

    # Make sure causal conv is right-aligned, so that the most recent samples
    # are never ignored. Thus we want:
    #           1  2  3  4
    # -> [0  0] 1  2  3  4  (padding)
    # ->           3    10  (conv with kernel of ones: 3=0+0+1+2, 10=1+2+3+4)
    # Note that this is different from tf.keras.layersConv1D(..., 'causal'),
    # which will pad 3 zeroes on the left and produce [1(=0+0+0+1), 6(=0+1+2+3)]
    # instead. The latter is less ideal, since it pads an extra zero and ignores
    # the last (and hence most recent) valid sample "4".
    self.assertAllEqual(outputs, [3, 10])

  @parameterized.named_parameters(
      {
          'testcase_name': 'model with stream wrapper on Conv1D',
          'get_model': conv_model,
          'conv_cell': tf.keras.layers.Conv1D
      }, {
          'testcase_name': 'model with stream wrapper on SeparableConv1D',
          'get_model': conv_model,
          'conv_cell': tf.keras.layers.SeparableConv1D
      }, {
          'testcase_name': 'model without stream wrapper on Conv1D',
          'get_model': conv_model_no_stream_wrapper,
          'conv_cell': tf.keras.layers.Conv1D
      })
  def test_stream_strided_convolution(self, get_model, conv_cell):
    # Test streaming convolutional layers with striding, dilation.
    cnn_filters = [1, 1, 1, 1]
    cnn_kernel_size = [3, 3, 3, 3]
    cnn_act = ['linear', 'linear', 'elu', 'elu']
    cnn_dilation_rate = [1, 1, 1, 2]
    cnn_strides = [2, 1, 3, 1]
    cnn_use_bias = [False, False, False, False]

    # prepare input data
    params = test_utils.Params(cnn_strides)
    x = np.arange(params.desired_samples)
    frequency = 2.0
    inp_audio = np.cos((2.0 * np.pi / params.desired_samples) * frequency *
                       x) + np.random.rand(1, params.desired_samples) * 0.5

    if conv_cell == tf.keras.layers.SeparableConv1D:
      kwargs = dict(
          depthwise_initializer=tf.keras.initializers.GlorotUniform(seed=123),
          pointwise_initializer=tf.keras.initializers.GlorotUniform(seed=456))
    else:
      kwargs = dict(
          kernel_initializer=tf.keras.initializers.GlorotUniform(seed=123))

    # Prepare Keras native model.
    model_native = conv_model_keras_native(params, conv_cell, cnn_filters,
                                           cnn_kernel_size, cnn_act,
                                           cnn_dilation_rate, cnn_strides,
                                           cnn_use_bias, **kwargs)
    model_native.summary()

    # prepare non stream model
    model = get_model(params, conv_cell, cnn_filters, cnn_kernel_size,
                      cnn_act, cnn_dilation_rate, cnn_strides, cnn_use_bias,
                      **kwargs)
    model.summary()

    # prepare streaming model
    model_stream = utils.to_streaming_inference(
        model, params, modes.Modes.STREAM_INTERNAL_STATE_INFERENCE)
    model_stream.summary()

    # run inference
    non_stream_out = model.predict(inp_audio)
    native_out = model_native.predict(inp_audio)
    stream_out = test.run_stream_inference(params, model_stream, inp_audio)

    # normalize output data and compare them
    channel = 0
    non_stream_out = non_stream_out[0, :, channel]
    native_out = native_out[0, :, channel]
    stream_out = stream_out[0, :, channel]

    min_len = min(stream_out.shape[0], non_stream_out.shape[0])
    stream_out = stream_out[0:min_len]
    native_out = native_out[0:min_len]
    non_stream_out = non_stream_out[0:min_len]
    self.assertAllEqual(non_stream_out.shape,
                        (params.desired_samples / np.prod(cnn_strides),))

    with self.subTest(name='stream_vs_non_stream'):
      self.assertAllClose(stream_out, non_stream_out)

    with self.subTest(name='non_stream_vs_native'):
      self.assertAllClose(non_stream_out, native_out)

if __name__ == '__main__':
  tf.test.main()


import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
import json
import os
from PIL import Image,ImageTk

def create_FBX(self,root_dir):
        self.frame = ttk.Frame(self.root, width=200, height=100)
        self.frame.pack_propagate(False)

        self.images_utilisees={ #Dictionnaire pour associer une image à chaque face du modèle
                "Avant":'',
                "Arrière":'',
                "Haut":'',
                "Bas":'',
                "Gauche":'',
                "Droite":''
                }

        #Permet de créer la commande à partir de tous les paramètres rentrés par l'utilisateur
        def generate_command_FBX():
                if test_generate(): #test si tous les paramètres nécessaires sont donnés
                        w,d,h=get_dimensions()
                        avant=self.images_utilisees["Avant"]
                        path=enter_path.get()
                        command='''python "'''+root_dir+'''\Converter\source\\fbx\FbxBuilder.py" --WDH '''+str(w)+","+str(d)+","+str(h)+''' --front "'''+avant+'''" -o "'''+path+'''"'''
                        if enter_name.get()!="":
                                name=enter_name.get()
                                command+=''' --name "'''+name+'''"'''
                        if self.images_utilisees["Arrière"]!="":
                                command+=''' --back "'''+self.images_utilisees["Arrière"]+'''"'''
                        if self.images_utilisees["Haut"]!="":
                                command+=''' --top "'''+self.images_utilisees["Haut"]+'''"'''
                        if self.images_utilisees["Bas"]!="":
                                command+=''' --bottom "'''+self.images_utilisees["Bas"]+'''"'''
                        if self.images_utilisees["Gauche"]!="":
                                command+=''' --left "'''+self.images_utilisees["Gauche"]+'''"'''
                        if self.images_utilisees["Droite"]!="":
                                command+=''' --right "'''+self.images_utilisees["Droite"]+'''"'''
                        self.generate_command(command)
                else :
                        self.launch_error('Missing arguments') #Si manque des paramètres

        #Création de la fenêtre pour choisir les png
        def choisir_png(text):
                nouvelle_fenetre = tk.Toplevel(self.root)
                nouvelle_fenetre.title("Nouvelle Fenêtre")
                nouvelle_fenetre.state("zoomed")

                #Création de la partie basse
                bot=ttk.Frame(nouvelle_fenetre)
                bot.pack(side=tk.BOTTOM,fill=tk.X)
                text_images=tk.Text(bot, height=8)
                text_images.pack(side=tk.LEFT,fill=tk.X, padx=2, pady=15, expand=True)
                contenu=text.get("1.0", tk.END)
                text_images.insert("0.0",contenu[0:len(contenu)-2])
                text_images.delete(tk.END)
                bot2=ttk.Frame(bot)
                bot2.pack(side=tk.RIGHT)
                size_label=ttk.Label(bot2,text="Choice of face : ")
                size_label.pack(side=tk.TOP)
                options = ["Avant", "Arrière","Haut","Bas","Gauche","Droite"]
                selected_option = tk.StringVar() # Créer une variable pour stocker la valeur sélectionnée
                combo_box = ttk.Combobox(bot2, textvariable=selected_option, values=options)
                combo_box.pack(side=tk.TOP,pady=5)

                #Récupère la face choisie
                def select(event):
                        self.selected_value = combo_box.get()

                #Ajoute l'image sélectionné dans l'entrée du bas et l'attribue à une face
                def add_image():
                        debut=''
                        text=''
                        if self.image_actuelle!='': #Vérifie qu'une image est sélectionnée
                                if len(self.image_labels)>1:
                                        for img_label in self.image_labels:
                                                img_label.configure(background='SystemButtonFace') #Repasse toute les images en mode "non-sélectionnée"
                                #Affiche l'entête correspondant à la face choisie avant le nom de l'image
                                if self.selected_value == "Avant":
                                        debut='Front'
                                        self.images_utilisees['Avant']=self.image_actuelle
                                        text='Front - '+ get_name(self.image_actuelle) +'\n'
                                elif self.selected_value == "Arrière":
                                        debut='Back'
                                        self.images_utilisees['Arrière']=self.image_actuelle
                                        text='Back - '+ get_name(self.image_actuelle) +'\n'
                                elif self.selected_value == "Haut":
                                        debut='Top'
                                        self.images_utilisees['Haut']=self.image_actuelle
                                        text='Top - '+ get_name(self.image_actuelle) +'\n'
                                elif self.selected_value == "Bas":
                                        debut='Bottom'
                                        self.images_utilisees['Bas']=self.image_actuelle
                                        text='Bottom - '+ get_name(self.image_actuelle) +'\n'
                                elif self.selected_value == "Gauche":
                                        debut='Left'
                                        self.images_utilisees['Gauche']=self.image_actuelle
                                        text='Left - '+ get_name(self.image_actuelle) +'\n'
                                elif self.selected_value == "Droite":
                                        debut='Right'
                                        self.images_utilisees['Droite']=self.image_actuelle
                                        text='Right - '+ get_name(self.image_actuelle) +'\n'

                                self.image_actuelle='' #Désélectionne l'image

                                #Verifie si il y a déja une image attribuée à la face choisie
                                contenu=text_images.get("1.0", tk.END)
                                occurrence = contenu.find(debut)
                                if occurrence != -1:
                                        # Si une occurrence est trouvée, supprimer l'ancienne suite
                                        fin_ligne = contenu.find("\n", occurrence)
                                        new_contenu=contenu[0:occurrence]+contenu[fin_ligne+1:len(contenu)-1]
                                        text_images.delete(f"0.0",tk.END)
                                        text_images.insert(tk.END,new_contenu)
                                text_images.insert(tk.END,text)

                #Renvoie l'affichage à la fenêtre principale et ferme cette fenêtre
                def validate():
                        contenu=text_images.get("1.0", tk.END)
                        text.delete(f"0.0",tk.END)
                        text.insert(tk.END,contenu)
                        nouvelle_fenetre.destroy()

                combo_box.bind("<<ComboboxSelected>>", select) # Associer une fonction à l'événement de sélection
                button1=ttk.Button(bot2,text="Add", padding=(40,5,40,5), command=lambda: add_image())
                button1.pack(side=tk.TOP)
                button2=ttk.Button(bot2,text="Validate", padding=(40,5,40,5), command=lambda: validate())
                button2.pack(side=tk.TOP)

                #Crée la frame où mettre treeview
                left=ttk.Frame(nouvelle_fenetre)
                left.pack(side=tk.LEFT,fill=tk.Y)

                #Crée la frame et le canva où mettre les images
                right=ttk.Frame(nouvelle_fenetre)
                right.pack(side=tk.LEFT,fill=tk.BOTH, expand=True)
                canvas_images = tk.Canvas(right)
                canvas_images.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

                self.image_actuelle='' #Image sélectionné
                self.image_labels=[] #Liste des images affichées
                self.selected_value='' #Face sélectionnée

                # Ajouter une barre de défilement verticale à droite du canevas
                scrollbar = ttk.Scrollbar(right, orient=tk.VERTICAL, command=canvas_images.yview)
                scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
                canvas_images.config(yscrollcommand=scrollbar.set)
                scrollbar.config(command=canvas_images.yview)

                #Récupère tous les png dans le dossier ouvert
                def lister_images_png(repertoire):
                        images_png = [f for f in os.listdir(repertoire) if f.lower().endswith(".png")]
                        return images_png

                #Retourne les images à partir des png
                def charger_images(repertoire):
                        images = []
                        images_png = lister_images_png(repertoire)

                        for image_png in images_png:
                                chemin_image = os.path.join(repertoire, image_png)
                                image = Image.open(chemin_image)
                                images.append((image, ImageTk.PhotoImage(image)))

                        return images

                #Affiche les images du dossier
                def afficher_images(liste_images,noms,directory,inner_frame, width, height=100):
                        def image_clicked(image_path,label): #Fonction pour sélectionner et surligner une image
                                self.image_actuelle=image_path
                                for img_label in self.image_labels:
                                        img_label.configure(background='SystemButtonFace') #Remet toute les images en "non-sélectionnée"
                                # Mettre en surbrillance l'image sélectionnée en changeant la couleur de fond
                                label.configure(background='blue')

                        self.image_labels=[]
                        id = 0
                        for (img, imgtk), nom in zip(liste_images, noms):
                                # Redimensionner l'image
                                imgtk_resized = ImageTk.PhotoImage(img.resize((width, height)))

                                # Afficher l'image redimensionnée dans le canevas
                                label_image = ttk.Label(inner_frame, image=imgtk_resized)
                                label_image.image = imgtk_resized  # Garantit que la référence à l'image est maintenue
                                label_image.grid(row=(id // 3)*2, column=id % 3,padx=5) # Les affiches par rangé de 3

                                # Associer le callback au clic de l'image
                                label_image.bind("<Button-1>", lambda event, path=directory + "\\" + nom, label=label_image: image_clicked(path,label))
                                self.image_labels.append(label_image)

                                #Enlève la partie ".png" du nom du fichier
                                for i in range(len(nom)):
                                        if (nom[i:i+4]=='.png'):
                                                nom=nom[0:i]
                                # Afficher le nom de l'image en dessous
                                label_name = ttk.Label(inner_frame, text=nom)
                                label_name.grid(row=(id // 3)*2 + 1, column=id % 3)

                                id += 1

                # Gère l'affichage dynamique
                def update_images(event):
                        item_selectionne = self.tree.selection() #Récupère l'item sélectionné dans le treeview
                        item_tag = self.tree.item(item_selectionne)['text'][-4:-1]+self.tree.item(item_selectionne)['text'][-1] #Récupère les 4 derniers caractère du nom du fichier
                        if item_tag==".png":
                                item_type='png'
                        else:
                                item_type='folder'

                        if item_selectionne:
                        # Si l'élément sélectionné dans l'arbre est un dossier un vérifie s'il contient des images et si oui on les affiche
                                if item_type == 'folder':
                                        # Récupérer le parent de l'élément sélectionné
                                        parent = self.tree.parent(item_selectionne)
                                        nom_parent=self.tree.item(parent)['text']

                                        # Si le parent est une chaîne vide, cela signifie que l'élément sélectionné est à la racine
                                        selected_directory = ""
                                        while nom_parent!="":
                                                selected_directory = nom_parent +"\\"+ selected_directory
                                                parent = self.tree.parent(parent)
                                                nom_parent=self.tree.item(parent)['text']
                                        selected_directory=selected_directory+"\\"+self.tree.item(item_selectionne)['text']

                                        selected_directory_path = (root_dir+"\\" +selected_directory)

                                        # Effacer les anciennes images
                                        for widget in canvas_images.winfo_children():
                                                widget.destroy()

                                        #création d'une frame qui va pouvoir contenir nos images
                                        inner_frame = ttk.Frame(canvas_images)
                                        canvas_images.create_window((0, 0), window=inner_frame, anchor=tk.NE)

                                        # Charger et afficher les nouvelles images avec leurs noms
                                        images = charger_images(selected_directory_path)
                                        noms=lister_images_png(selected_directory_path)
                                        width=int(right.winfo_width()/3*0.92) #Ajuste la taille des images à l'écran
                                        afficher_images(images,noms,selected_directory_path,inner_frame,width)

                                        canvas_images.update_idletasks()  # Met à jour le canevas avant de configurer la barre de défilement
                                        canvas_images.config(scrollregion=canvas_images.bbox(tk.ALL))

                                #si l'élément est un png on l'affiche simplement
                                elif item_type == 'png':
                                        self.image_actuelle=self.tree.item(item_selectionne)['text']
                                        parent = self.tree.parent(item_selectionne)
                                        nom_parent=self.tree.item(parent)['text']
                                        self.image_labels=[]

                                        # Si le parent est une chaîne vide, cela signifie que l'élément sélectionné est à la racine
                                        selected_directory = ""
                                        while nom_parent!="":
                                                selected_directory = nom_parent +"\\"+ selected_directory
                                                parent = self.tree.parent(parent)
                                                nom_parent=self.tree.item(parent)['text']
                                        selected_directory=selected_directory+"\\"+self.tree.item(item_selectionne)['text']

                                        selected_directory_path = (root_dir+"\\" +selected_directory)

                                        # Effacer les anciennes images
                                        for widget in canvas_images.winfo_children():
                                                widget.destroy()

                                        #On affiche l'image
                                        image = Image.open(selected_directory_path)
                                        imgtk = ImageTk.PhotoImage(image)
                                        label_image = ttk.Label(canvas_images, image=imgtk)
                                        label_image.image = imgtk  # Garantit que la référence à l'image est maintenue
                                        label_image.pack(side=tk.TOP, anchor="center")

                #Création de l'arborescence de fichier en utilisant les fonctions dans GUI
                self.tree = ttk.Treeview(left, show="tree",height=30)
                self.tree.pack(side=tk.LEFT,fill=tk.BOTH)
                self.tree.column("#0", width=400)
                self.fsobjects = {}
                self.file_image = tk.PhotoImage(file=root_dir+"/ToolBox/Icons/file.png") #On affecte file.png comme icone des fichiers
                self.folder_image = tk.PhotoImage(file=root_dir+"/ToolBox/Icons/folder.png") #On affecte folder.png comme icone des dossiers
                self.tree.tag_bind("fstag", "<<TreeviewOpen>>", self.item_opened)
                self.load_tree(root_dir,"")
                self.tree.bind("<<TreeviewSelect>>", update_images)

        # Récupère uniquement le nom de l'image (enlève le ".png")
        def get_name(path):
                ind=0
                for i in range(len(path)):
                        if path[i]=="\\":
                                ind=i
                path=path[ind+1:len(path)]
                for i in range(len(path)):
                        if path[i:i+4]=='.png':
                                path=path[0:i]
                return path

        # Choisi le path du dossier de sortie
        def choisir_path(enter):
                file_path = filedialog.askdirectory(initialdir=os.getcwd())
                enter.delete(0, tk.END)  # Efface le contenu actuel de l'Entry
                enter.insert(0, file_path)

        #Choisir le JSON pour les dimensions
        def choisir_JSON(entry):
                os.chdir(root_dir+"/Converter/output/OGrEE/templates")
                fichier = filedialog.askopenfilename(filetypes=[("Fichiers JSON", "*.json")], initialdir=os.getcwd())
                os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
                # Affiche le lien du fichier dans l'Entry
                entry.delete(0, tk.END)  # Efface le contenu actuel de l'Entry
                entry.insert(0, fichier)  # Insère le lien du fichier choisi

        #Test si tous les paramètres nécessaires sont renseignés
        def test_generate():
                w,d,h=get_dimensions()
                avant=self.images_utilisees['Avant']
                out=enter_path.get()
                if (w!="" and d!="" and h!="" and avant!="" and out!=""):
                        return True
                else :
                        return False
        # Modifie la frame en fonction du mode de dimensions choisi
        def on_select(event):
                selected_value = combo_box.get()
                for widget in dimension_display.winfo_children():
                        widget.destroy()
                # Si mode manuel : on affiche les 3 entrées avec des valeurs de bases pré remplies
                if selected_value == "manually (cm)":
                        w_label=ttk.Label(dimension_display,text=" w ")
                        w_label.pack(side=tk.LEFT,padx=10)
                        w_entry=ttk.Entry(dimension_display,width=5)
                        w_entry.insert(0,"434")
                        w_entry.pack(side=tk.LEFT)
                        d_label=ttk.Label(dimension_display,text=" d ")
                        d_label.pack(side=tk.LEFT,padx=10)
                        d_entry=ttk.Entry(dimension_display,width=5)
                        d_entry.insert(0,"755")
                        d_entry.pack(side=tk.LEFT)
                        h_label=ttk.Label(dimension_display,text=" h ")
                        h_label.pack(side=tk.LEFT,padx=10)
                        h_entry=ttk.Entry(dimension_display,width=5,)
                        h_entry.insert(0,"87")
                        h_entry.pack(side=tk.LEFT)
                #Si on choisi le JSON : on affiche un bouton pour choisir le fichier
                elif selected_value == "with a JSON":
                        parcourir_JSON=ttk.Button(dimension_display,text="Choose JSON",width=20, command=lambda: choisir_JSON(JSON_entry))
                        parcourir_JSON.pack(side=tk.LEFT,padx=10)
                        JSON_entry=ttk.Entry(dimension_display)
                        JSON_entry.pack(side=tk.LEFT,padx=10,fill=tk.X, expand=True)

        # Récupère les dimensions sélectionnées
        def get_dimensions():
                w,d,h='','',''
                widgets=[]
                for widget in dimension_display.winfo_children():
                        if widget.winfo_class()=="TEntry":
                                widgets.append(widget)
                if len(widgets)==3 : #Si 3 entrées = manuel
                        w=widgets[0].get()
                        d=widgets[1].get()
                        h=widgets[2].get()
                elif len(widgets)==1: #Si 1 entré = JSON
                        JSON_path=widgets[0].get()
                        try:
                                with open(JSON_path, 'r') as file:
                                        data = json.load(file)
                                if "sizeWDHmm" in data:
                                        # Accéder à la liste de "sizeWDHmm"
                                        size_data = data["sizeWDHmm"]
                                        # Accéder aux éléments individuels de la liste
                                        if len(size_data) == 3:
                                                w,d,h = size_data
                                                w=w/10 #On convertit les mesures récupérées (en mm) en cm
                                                d=d/10
                                                h=h/10
                                else :
                                        self.terminal.insert(tk.END,f"The file {JSON_path} do not contains dimensions. \n")
                        except FileNotFoundError:
                                self.terminal.insert(tk.END,f"Error : the file {JSON_path} was not found. \n")
                        except json.JSONDecodeError as e:
                                self.terminal.insert(tk.END,f"Erreur lors du décodage JSON : {e} \n")
                return w,d,h

        #Contenu de la frame
        label = ttk.Label(self.frame, text="FBX Converter")
        label.pack(pady=5)

        front = ttk.Frame(self.frame)
        front.pack(fill=tk.X, pady=20)
        front_label = ttk.Label(front, text="Choose your pictures :", anchor="w")
        front_label.pack(fill=tk.X,side=tk.TOP, pady=20, padx=15)

        images=tk.Text(front,height=6)
        images.pack(side=tk.LEFT, padx=20, fill=tk.X, expand=True)
        front_parcourir = ttk.Button(front, text="Browse", command=lambda: choisir_png(images), width=20)
        front_parcourir.pack(side=tk.RIGHT, padx=20,pady=20)

        dimensions=ttk.Frame(self.frame)
        dimensions.pack(side=tk.TOP, fill=tk.X,pady=5)
        size_label=ttk.Label(dimensions,text="Choose the dimensions of your component : ")
        size_label.pack(side=tk.LEFT,pady=20, padx=15)
        options = ["manually (cm)", "with a JSON"]
        selected_option = tk.StringVar() # Créer une variable pour stocker la valeur sélectionnée
        combo_box = ttk.Combobox(dimensions, textvariable=selected_option, values=options)
        combo_box.pack(side=tk.LEFT,pady=20)
        combo_box.set("manually (cm)") # Définir une option par défaut
        combo_box.bind("<<ComboboxSelected>>", on_select) # Associer une fonction à l'événement de sélection
        enter_name=ttk.Entry(dimensions,width=50)
        enter_name.pack(side=tk.RIGHT, padx=10)
        label_name=ttk.Label(dimensions,text="Choose your FBX file name :")
        label_name.pack(side=tk.RIGHT)

        dimension_display=ttk.Frame(self.frame)
        dimension_display.pack(side=tk.TOP, fill=tk.X,pady=10)

        path=ttk.Frame(self.frame)
        path.pack(side=tk.TOP, fill=tk.X)
        enter_button=ttk.Button(path, text="Out path", command=lambda: choisir_path(enter_path))
        enter_button.pack(pady=20,padx=10 ,side=tk.LEFT)
        enter_path=ttk.Entry(path, width=100)
        enter_path.pack(pady=20,padx=10 , fill=tk.X)

        bot=ttk.Frame(self.frame)
        bot.pack(side=tk.BOTTOM, fill=tk.X)
        finish_button=ttk.Button(bot, text="Generate", padding=(0,10,0,10), width=20, command=lambda: generate_command_FBX())
        finish_button.pack(pady=20,padx=10)

        return self.frame


import json
from pprint import pprint

import requests

URLS = {
    "base": "https://archiverse.guide/api/posts/"
}

COMMUNITIES = {
    "US": "14866558073457096100",
    "EU": "14866558073328768494",
    "JP": "14866558073315036717",
}

HEADERS = {
    "content-type": "application/json",
    "Accept": "application/json",
}

DAYS_IN_MONTH = {
    1: 31,
    2: 28,
    3: 31,
    4: 30,
    5: 31,
    6: 30,
    7: 31,
    8: 31,
    9: 31,
    10: 31,
    11: 30,
    12: 31,
}

def prepare_post(community, start_date, end_date, page=1):
    post = {
        "textSearch": "",
        "gameId": "",
        "titleId": "",
        "name": "",
        "screenName": "",
        "isDrawingOnly": False,
        "isScreenshotOnly": False,
        "orderByDateDescending": False,
        "reverse": False,
        "startDate": "{}T19:00:00.000Z",
        "endDate": "{}T19:00:00.000Z",
        "sortEmpathy": 0,
        "sortReplyCount": 0,
        "page": 1
    }

    post["gameId"] = community
    post["startDate"] = post["startDate"].format(start_date)
    post["endDate"] = post["endDate"].format(end_date)
    post["page"] = page

    return post

def main():
    community = COMMUNITIES["US"]
    start_date = "2015-08-01"
    end_date = "2015-08-31"
    page = 801
    running = True

    with open("/var/projects/pokemon_art_museum/output/us.dat", "w") as fh:
        while running:
            post = prepare_post(community, start_date, end_date, page)
            resp = requests.post(URLS["base"],
                                 data=json.dumps(post),
                                 headers=HEADERS)
            if resp.status_code == 200:
                data = resp.json()
            else:
                print("STATUS CODE", resp.status_code)
                #print(resp.text)
                input("HANGING ON PAGE: " + str(page))
                continue
            print(resp.status_code, "start", start_date, "end", end_date,
                  "currentPage", data["currentPage"], "pageCount",
                  data["pageCount"], "FirstVisible", data["firstRowOnPage"],
                  "LastVisible", data["lastRowOnPage"],
                  "RES", len(data["results"]))

            # Advance date if needed
            if len(data["results"]) != 20:
                page = 1
                y = int(start_date.split("-")[0])
                m = int(start_date.split("-")[1])

                m += 1
                if m > 12:
                    m = 1
                    y += 1
                    input("YEAR BREAK.")

                start_date = str(y) + "-" + ("0" + str(m))[-2:] + "-01"

                if m == 2 and y == 2016:
                        d = 29
                else:
                    d = ("0" + str(DAYS_IN_MONTH[m]))[-2:]
                end_date = str(y) + "-" + ("0" + str(m))[-2:] + "-" + d
            else:
                page += 1

            # Log the posts
            posts = data.get("results", [])
            for p in posts:
                if p.get("screenShotUri", "") != "":
                    fh.write(json.dumps(p) + "\n")
    return True

if __name__ == "__main__":
    main()


from flask import Blueprint, jsonify, request, make_response
import hashlib
import io, pyexcel
from datetime import datetime
import json
from .authentication import requires_auth
from .models import Customer, Item, ShippingAddress, Subscription
from . import db

api = Blueprint('api', __name__)

@api.route('/', methods=['GET'])
@requires_auth
def index():
    return jsonify({'msg': 'Popcorn Cove Subscriptions version 1'})

@api.context_processor
def create_model(model, data):
  item = model()
  item.from_dict(data)
  db.session.add(item)
  db.session.commit()
  return jsonify(item.to_dict()), 201

@api.context_processor
def update_model(model, id, data):
  item = model.query.get(id)
  item.from_dict(data)
  db.session.add(item)
  db.session.commit()
  return jsonify(item.to_dict()), 200

@api.context_processor
def delete_model(model, id):
    item = model.query.get(id)
    className = model.__name__
    if item:
        db.session.delete(item)
        db.session.commit()
        return jsonify({'msg': className + ' deleted', 'error': False}), 200
    else:
        return jsonify({'msg': className + ' not found', 'error': True}), 400

# Customer Routes
@api.route('/customer', methods=['GET'])
@requires_auth
def get_customers():
  customers = Customer.query.all()
  return jsonify([i.to_dict() for i in customers]), 200

@api.route('/customer/<int:id>', methods=['GET'])
@requires_auth
def get_customer(id):
  customer = Customer.query.get(id)
  return jsonify(customer.to_dict()), 200

@api.route('/customer', methods=['POST'])
@requires_auth
def create_customer():
  data = request.get_json()
  return create_model(Customer, data)

@api.route('/customer/<int:id>', methods=['PUT'])
@requires_auth
def update_customer(id):
  data = request.get_json()
  return update_model(Customer, id, data)

@api.route('/customer/<int:id>', methods=['DELETE'])
@requires_auth
def delete_customer(id):
  return delete_model(Customer, id)

# Subscription Routes
@api.route('/subscription', methods=['GET'])
@requires_auth
def get_subscriptions():
  subscriptions = Subscription.query.all()
  return jsonify([i.to_dict() for i in subscriptions]), 200

@api.route('/subscription/<int:id>', methods=['GET'])
@requires_auth
def get_subscription(id):
  subscriptions = Subscription.query.filter_by(customerID=id).all()
  return jsonify([i.to_dict() for i in subscriptions]), 200

@api.route('/subscription', methods=['POST'])
@requires_auth
def create_subscription():
  data = request.get_json()
  return create_model(Subscription, data)

@api.route('/subscription/<int:id>', methods=['PUT'])
@requires_auth
def update_subscription(id):
  data = request.get_json()
  return update_model(Subscription, id, data)

@api.route('/subscription/<int:id>', methods=['DELETE'])
@requires_auth
def delete_subscription(id):
  return delete_model(Subscription, id)

# ShippingAddress Routes
@api.route('/shippingaddress', methods=['GET'])
@requires_auth
def get_shippingaddresses():
  shippingaddresses = ShippingAddress.query.all()
  return jsonify([i.to_dict() for i in shippingaddresses]), 200

@api.route('/shippingaddress/<int:id>', methods=['GET'])
@requires_auth
def get_shippingaddress(id):
  """get all addresses by customer id"""
  shippingaddresses = ShippingAddress.query.filter_by(customerID=id).all()
  return jsonify([i.to_dict() for i in shippingaddresses]), 200

@api.route('/shippingaddress', methods=['POST'])
@requires_auth
def create_shippingaddress():
  data = request.get_json()
  return create_model(ShippingAddress, data)

@api.route('/shippingaddress/<int:id>', methods=['PUT'])
@requires_auth
def update_shippingaddress(id):
  data = request.get_json()
  return update_model(ShippingAddress, id, data)

@api.route('/shippingaddress/<int:id>', methods=['DELETE'])
@requires_auth
def delete_shippingaddress(id):
  return delete_model(ShippingAddress, id)

# Item Routes
@api.route('/item', methods=['GET'])
@requires_auth
def get_items():
  items = Item.query.all()
  return jsonify([i.to_dict() for i in items]), 200

@api.route('/item/<int:id>', methods=['GET'])
@requires_auth
def get_item(id):
  item = Item.query.get(id)
  return jsonify(item.to_dict()), 200

@api.route('/item', methods=['POST'])
@requires_auth
def create_item():
  data = request.get_json()
  return create_model(Item, data)

@api.route('/item/<int:id>', methods=['PUT'])
@requires_auth
def update_item(id):
  data = request.get_json()
  return update_model(Item, id, data)

@api.route('/item/<int:id>', methods=['DELETE'])
@requires_auth
def delete_item(id):
  # migrate all subscriptions with FK for that item
  migrationID = request.args.get('migrate')
  subscriptions = Subscription.query.filter_by(itemID=id).all()
  for i in subscriptions:
    i.itemID = migrationID
    db.session.add(i)
  db.session.commit()
  # then delete the item
  return delete_model(Item, id)

@api.route('/export', methods=['GET'])
@requires_auth
def export_subscriptions():
  year = request.args.get('year')
  month = request.args.get('month')
  date = datetime.strptime('{}-{}'.format(year, month), '%Y-%m')
  subscriptions = Subscription.query\
    .filter(date >= Subscription.startDate)\
    .filter(date <= Subscription.stopDate)\
    .join(Customer, Subscription.customerID == Customer.id)\
    .join(Item, Subscription.itemID == Item.id)\
    .join(ShippingAddress, Subscription.shippingAddressID == ShippingAddress.id)\
    .add_columns(
      Subscription.id,
      Subscription.note,
      Customer.name,
      Customer.email,
      Customer.phone,
      ShippingAddress.address,
      ShippingAddress.city,
      ShippingAddress.state,
      ShippingAddress.zip,
      Item.name.label("itemName"))\
    .all()

  header = ["SUBSCRIPTION ID", "NAME","STREET","CITY","STATE", "ZIP", "EMAIL", "PHONE", "ITEM", "NOTE"]
  data = [ header ]
  for i in subscriptions:
    sub = [i.id, i.name, i.address, i.city, i.state, i.zip, i.email, i.phone, i.itemName, i.note]
    data.append(sub)
  sheet = pyexcel.Sheet(data)
  dest = io.StringIO()
  sheet.save_to_memory("csv", dest)
  output = make_response(dest.getvalue())
  output.headers["Content-Disposition"] = "attachment; filename=export_{}-{}.csv".format(year, month)
  output.headers["Content-type"] = "text/csv"
  return output


import click

from flask import Flask

import config
from lib.app import create_app
from plugins.db import db
from lib.utils import blueprint_template
from lib.migration import Migration

app = create_app(Flask(config.APP_NAME))

@click.group()
def manage():
    pass

@click.command()
def test():
    """Run tests"""
    import unittest
    suite = unittest.TestLoader()\
                .discover("tests", pattern="*_test.py")
    unittest.TextTestRunner(verbosity=config.TEST_VERBOSITY).run(suite)

manage.add_command(test)

@click.group("migration", options_metavar="\b")
def migration():
    """Database migration"""
    pass

manage.add_command(migration)

@click.command("init", options_metavar="\b")
def migration_init():
    """Initialize database migration structure"""
    Migration(app).init()

migration.add_command(migration_init)

@click.command("create", options_metavar="\b")
@click.argument("name")
def migration_create(name):
    """Create a migration file"""
    Migration(app).migration(name)

migration.add_command(migration_create)

@click.command("up", options_metavar="\b")
def migration_up():
    """Run migration revision up"""
    Migration(app).migrate("up")

migration.add_command(migration_up)

@click.command("down", options_metavar="\b")
def migration_down():
    """Run migration revision down"""
    Migration(app).migrate("down")

migration.add_command(migration_down)

@click.command("blueprint", options_metavar="\b")
@click.argument("name")
@click.option("--path", default=None)
@click.option("--templates", default=None)
def blueprint(name, path, templates):
    """Create blueprint structure"""
    templates = templates or "templates"
    path = path or name
    blueprint_template(name, templates)

manage.add_command(blueprint)

@click.command("runserver")
@click.option("--host", default="0.0.0.0")
@click.option("--port", default=5000)
def runserver(host, port):
    """Development server"""
    app.run(host, port)

manage.add_command(runserver)

@click.command()
def shell():
    """Python shell with app locales"""
    import code

    with app.test_request_context():
        code.interact(None, local=dict(app=app, db=db))

manage.add_command(shell)


import os
import sys

import numpy as np
import time
sys.path.append(os.path.dirname(__file__) + "/../")

sys.path.append("./lib/coco/PythonAPI/")
from pycocotools.coco import COCO

from scipy.misc import imread, imsave
import scipy.io as sio
from config import load_config
from dataset.factory import create as create_dataset
from nnet import predict
from dataset.pose_dataset import data_to_input

from multiperson.detections import extract_detections

class DataItem:
    pass

cfg = load_config("demo/get_training_data.yaml")

dataset = create_dataset(cfg)

ann_file = "/home/gpu_server/lyj/coco/annotations/person_keypoints_train2014.json"
file_head = '/home/gpu_server/lyj/coco/train2014/'
coco = COCO(ann_file)
imgIds = coco.getImgIds()
sess, inputs, outputs = predict.setup_pose_prediction(cfg)

data = []
data_35 = []
pair = []
counter = 0

for imgId in imgIds:
    item = DataItem()
    pair_item = DataItem()

    img = coco.loadImgs(imgId)[0]
    item.im_path = file_head + img["file_name"]
    item.im_size = [3, img["height"], img["width"]]
    item.coco_id = imgId
    annIds = coco.getAnnIds(imgIds=img['id'], iscrowd = False)
    anns = coco.loadAnns(annIds)

    has_people = len(anns) > 0
    if has_people:
        # get CNN output :
        # scmap, locref, pairwise_diff
        input = imread(item.im_path, mode = 'RGB')
        image_batch = data_to_input(input)
        outputs_np = sess.run(outputs, feed_dict={inputs: image_batch})
        scmap, locref, pairwise_diff = predict.extract_cnn_output(
            outputs_np, cfg, dataset.pairwise_stats)

        item.scmap = scmap
        item.locref = locref
        item.pairwise_diff = pairwise_diff
        pair_item.pairwise_diff = pairwise_diff
        # get GT for this image
        all_person_keypoints = []
        for ann in anns: # loop through each person
            person_keypoints = []
            if ann["num_keypoints"] != 0:
                for i in range(cfg.num_joints):
                    x_coord = ann["keypoints"][3 * i]
                    y_coord = ann["keypoints"][3 * i + 1]
                    visibility = ann["keypoints"][3 * i + 2]
                    if visibility != 0: # i.e. if labeled
                        person_keypoints.append([i, x_coord, y_coord])
                all_person_keypoints.append(np.array(person_keypoints))
        if not all_person_keypoints:
            continue
        item.joints = all_person_keypoints
    else:
        continue
    counter += 1
    if counter % 10 == 0 :
        print ('processing img (%d--%d)'%(counter,counter+10))
    if counter <= 500:
        pair.append(pair_item)
    if counter <= 35000:
        data_35.append(item)
    data.append(item)
    if counter >= 10 :
        dataset = np.asarray(data)
        sio.savemat('data_10.mat',{'dataset':dataset})
        raise
#save files
pair_set = np.asarray(pair)
dataset = np.asarray(data)
dataset_35 = np.asarray(data_35)
sio.savemat('gt_output.mat',{'dataset':dataset})
sio.savemat('gt_output_35.mat',{'dataset':dataset_35})
sio.savemat('pair.mat',{'pairwise':pair_set})
print ('finished')


"""
Demonstrates how to use the `ChatInterface` to create two bots that chat with each
other.
"""

import panel as pn
from openai import AsyncOpenAI

pn.extension()

async def callback(
    contents: str,
    user: str,
    instance: pn.chat.ChatInterface,
):
    if user in ["User", "Happy Bot"]:
        callback_user = "Nerd Bot"
        callback_avatar = "ðŸ¤“"
    elif user == "Nerd Bot":
        callback_user = "Happy Bot"
        callback_avatar = "ðŸ˜ƒ"

    prompt = f"Think profoundly about {contents}, then ask a question."
    response = await aclient.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        stream=True,
        max_tokens=250,
        temperature=0.1,
    )
    message = ""
    async for chunk in response:
        part = chunk.choices[0].delta.content
        if part is not None:
            message += part
            yield {"user": callback_user, "avatar": callback_avatar, "object": message}

    if len(instance.objects) % 6 == 0:  # stop at every 6 messages
        instance.send(
            "That's it for now! Thanks for chatting!", user="System", respond=False
        )
        return
    instance.respond()

aclient = AsyncOpenAI()
chat_interface = pn.chat.ChatInterface(callback=callback)
chat_interface.send(
    "Enter a topic for the bots to discuss! Beware the token usage!",
    user="System",
    respond=False,
)
chat_interface.servable()


from ...... import oscar as mo
from .....web import MarsRequestHandler

class TestWebHandler(MarsRequestHandler):
    async def get(self):
        ref = await mo.actor_ref("TestActor1", address=self._supervisor_addr)
        self.write(str(await ref.get_arg()))

web_handlers = {
    "/test_actor1/test_api": TestWebHandler,
}


from django.shortcuts import render, get_object_or_404
from django.http import HttpRequest, HttpResponse
import datetime
from .models import Category, Product
from basketapp.models import Basket
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

# Create your views here.

def undex(request: HttpRequest):
    products = Product.objects.all()

    return render(request, 'mainapp/index.html', {
        'products': products,
    })

def contact(request: HttpRequest):
    title = 'о нас'
    visit_date = datetime.datetime.now()

    locations = [
        {
            'city': 'Москва',
            'phone': '+7-888-888-8888',
            'email': 'info@geekshop.ru',
            'address': 'В пределах МКАД',
        },
        {
            'city': 'Екатеринбург',
            'phone': '+7-777-777-7777',
            'email': 'info_yekaterinburg@geekshop.ru',
            'address': 'Близко к центру',
        },
        {
            'city': 'Владивосток',
            'phone': '+7-999-999-9999',
            'email': 'info_vladivostok@geekshop.ru',
            'address': 'Близко к океану',
        },
    ]

    return render(request, 'mainapp/contact.html', {
        'title': title,
        'visit_date': visit_date,
        'locations': locations
    })

# def get_current_basket(current_user):
#     basket = Basket.objects.filter(user=current_user) if current_user.is_authenticated else None
#
#     return basket

def products(request, category_slug=None, page=1):
    title = 'продукты'
    links_menu = Category.objects.filter(is_valid=True)
    products = Product.objects.filter(category__slug=category_slug,
                                      available=True) if category_slug else Product.objects.filter(available=True,
                                                                                category__is_valid=True)
    category = get_object_or_404(Category, slug=category_slug,is_valid=True) if category_slug else None

    provider = Paginator(products, 1)

    try:
        products_provider = provider.page(page)
    except PageNotAnInteger:
        products_provider = provider.page(1)
    except EmptyPage:
        products_provider = provider.page(provider.num_pages)

    return render(request,
                  'mainapp/products.html',
                  {'title':title,
                   'category': category,
                   'links_menu': links_menu,
                   'provider': products_provider,
                   })

def product_detail(request, slug=None):
    links_menu = Category.objects.filter(is_valid=True)
    product = get_object_or_404(Product, slug=slug, available=True, category__is_valid=True, )
    products = Product.objects.exclude(slug=slug).filter(category__slug=product.category.slug, available=True,
                                                         category__is_valid=True, )
    return render(request, 'mainapp/product.html', {'product': product,
                                                    'links_menu': links_menu,
                                                    'title': f'Товар: {product.name}',
                                                    'products': products,
                                                    })

# def get_referer_view(request, default=None):
#     '''
#     Return the referer view of the current request
#
#     Example:
#
#         def some_view(request):
#             ...
#             referer_view = get_referer_view(request)
#             return HttpResponseRedirect(referer_view, '/accounts/login/')
#     '''
#
#     # if the user typed the url directly in the browser's address bar
#     referer = request.META.get('HTTP_REFERER')
#     if not referer:
#         return default


from telegram.ext import Updater, CommandHandler, MessageHandler, Filters

from datetime import datetime, timedelta
import requests as req
import logging
import time
from random import randint

BOT_TOKEN = "497378988:AAHE2cKiqsoT0APiraNrV2teWPLsGgc4DfU"
SIMULATED_PRICES = {
    "ETH" : 439,
    "BTC" : 1100,
    "TL" : 0.25
}
ALLOWED_CURRENCIES = ['Scoin','ETH', 'BTC', 'TL']

def ts2string(ts, fmt="%Y-%m-%d %H:%M"):
    dt = datetime.fromtimestamp(ts)
    return dt.strftime(fmt)

def string2ts(string, fmt="%Y-%m-%d %H:%M"):
    dt = datetime.strptime(string, fmt)
    t_tuple = dt.timetuple()
    return int(time.mktime(t_tuple))

### helpers above this line

def buy(bot, update, *args, **kwargs):
    """
    Simulate purchase experience with graphical offerings
    """
    params = list(kwargs.items())[0][1]
    if len(params) != 1:
        bot.send_message(chat_id=update.message.chat_id, text="Give me something like '/buy amount'")
        return

    bot.send_message(chat_id=update.message.chat_id, text="Please wait...")
    bot.send_message(chat_id=update.message.chat_id, text="Transaction accomplished! Look at you rich fella.")

def bot_help(bot, update):
    """
    List available commands
    """
    bot.send_message(chat_id=update.message.chat_id,
                    text="Commands:\n\n/start - make the first move\n/history date time - tell me that price!\n/convert cur1 cur2 - conversion is my profession\n/current - tell me current price\n/buy - buy some Scoins\n\n")

def convert(bot, update, *args, **kwargs):
    """
    Convert first one to second one considering current prices.
    """

    params = list(kwargs.items())[0][1]
    if len(params) != 2:
        bot.send_message(chat_id=update.message.chat_id, text="Give me something like '/convert cur1 cur2' where cur1 and cur2 are one of 'ETH', 'BTC', 'TL'")
        return

    if not params[0] in ALLOWED_CURRENCIES and params[1] in ALLOWED_CURRENCIES:
        bot.send_message(chat_id=update.message.chat_id, text="Your currencies must be one of 'Scoin', 'ETH', 'BTC', 'TL'")
        return

    cur1, cur2 = params[0], params[1]
    formatted_ts = None
    if cur1 == 'Scoin' or cur2 == 'Scoin':
        r = req.get('https://devakademi.sahibinden.com/ticker')
        response = r.json()
        timestamp = response["date"] / 1000
        price = response["value"]
        formatted_ts = ts2string(timestamp)

    if not formatted_ts:
        formatted_ts = ts2string(int(time.time()))

    if cur1 == 'Scoin':
        price1 = price
    else:
        price1 = SIMULATED_PRICES[cur1]
    if cur2 == 'Scoin':
        price2 = price
    else:
        price2 = SIMULATED_PRICES[cur2]
    rate = price1 / price2
    text = cur1 + " is " + str(rate) + " " + cur2 +" at " + formatted_ts
    bot.send_message(chat_id=update.message.chat_id, text=text)

def history(bot, update, *args, **kwargs):
    """
    Tell past prices of Scoin for given date and time parameters
    """
    params = list(kwargs.items())[0][1]

    if len(params) != 2:
        text = "Tell me something I can't refuse. To illustrate, '/history 2017-12-10 14:34'"
        bot.send_message(chat_id=update.message.chat_id, text=text)
        return

    date = params[0]
    time = params[1]
    try:
        datetime.strptime(date, "%Y-%m-%d")
    except ValueError:
        text = "Please give your date in '%Y-%m-%d' format."
        bot.send_message(chat_id=update.message.chat_id, text=text)
        return
    try:
        datetime.strptime(time, "%H:%M")
    except ValueError:
        text = "Please give your time in '%H:%M' format."
        bot.send_message(chat_id=update.message.chat_id, text=text)
        return

    date_time = ' '.join([date,time])
    timestamp = string2ts(date_time)

    r = req.get('https://devakademi.sahibinden.com/history')
    response = r.json()
    price = None
    for item in response:
        if item['date'] == timestamp:
            print("found")
            price = item['value']

    # simulate in case it isn't found, which is always since user can't give
    # second information which was used to generate timestamp in history data
    # we could look up nearest price info but I better simulate it and develop another feature for this hackathon
    if not price:
        price = 1000 + randint(0, 100)
    text = "Scoin at " + date_time + " is " + str(price) + " $"

    bot.send_message(chat_id=update.message.chat_id, text=text)

def current(bot, update):
    """
    Tell current Scoin price, sends a HTTP GET only last price expired
    """

    r = req.get('https://devakademi.sahibinden.com/ticker')
    response = r.json()
    timestamp = response["date"] / 1000
    price = response["value"]
    formatted_ts = ts2string(timestamp)
    bot.send_message(chat_id=update.message.chat_id,
                    text="1 Scoin = "+str(price)+ " $ at "+formatted_ts)

def unknown(bot, update):
    """
    Warn in case of invalid commands
    """
    bot.send_message(chat_id=update.message.chat_id,
                    text="Sorry, I didn't understand. '"+update.message.text+"' is NOT a valid command.")

def start(bot, update):
    """
    Start conversation
    """
    bot.send_message(chat_id=update.message.chat_id, text="I'm your Scoin helper, please talk to me! Type /help to see commands.")

if __name__ == "__main__":
    logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
    updater = Updater(token=BOT_TOKEN)
    dispatcher = updater.dispatcher

    start_handler = CommandHandler('start', start)
    unknown_handler = MessageHandler(Filters.command, unknown)
    current_handler = CommandHandler('current', current)
    history_handler = CommandHandler('history', history, pass_args=True)
    convert_handler = CommandHandler('convert', convert, pass_args=True)
    help_handler = CommandHandler('help', bot_help)
    buy_handler = CommandHandler('buy', buy, pass_args=True)

    dispatcher.add_handler(start_handler)
    dispatcher.add_handler(current_handler)
    dispatcher.add_handler(history_handler)
    dispatcher.add_handler(convert_handler)
    dispatcher.add_handler(help_handler)
    dispatcher.add_handler(buy_handler)
    dispatcher.add_handler(unknown_handler)

    updater.start_polling()


## IMDb 페이지에서 현재 상영 중인 영화정보 수집하기  https://www.imdb.com/list/ls016522954/?ref_=nv_tvv_dvd

## 제목, 평점(metascore), 감독, 배우 찾기
# 제목: h3.lister-item-header>a
# 평점: div.ipl-rating-widget div.small > span.ipl-rating-star__rating
# 감독: p.text-muted.text-small>a
# 배우: p.text-muted.text-small>a
# 장르: p.text-muted.text-small>span.genre

## 코드를 통해 데이터 수집하기(select함수 이용)
'''
import requests
from bs4 import BeautifulSoup

raw = requests.get("https://www.imdb.com/list/ls016522954/?ref_=nv_tvv_dvd", headers={"User-Agent" : "Mozilla/5.0"})
html = BeautifulSoup(raw.text, 'html.parser')

container = html.select("div.lister-item-content")
for c in container :
    title = c.select_one("h3.lister-item-header>a").text
    metascore = c.select_one(" div.ipl-rating-widget div.small > span.ipl-rating-star__rating")
    info = c.select("p.text-muted.text-small")
    director = info[1].select("a")
    genre = info[0].select("span.genre")

    print("제목: ", title)
    print("평점: ", metascore.text)
    print("감독 및 배우: ")
    for d in director:
        print(d.text)
    for g in genre:
        print(g.text)
    print("="*50)

##### 평점 안적힌 영화 오류 해결 방법은???
'''

## 액션 장르의 영화만 출력하기(선택자 사용)

import requests
from bs4 import BeautifulSoup

raw = requests.get("https://www.imdb.com/list/ls016522954/?ref_=nv_tvv_dvd", headers={"User-Agent" : "Mozilla/5.0"})
html = BeautifulSoup(raw.text, 'html.parser')

container = html.select("div.lister-item-content")
for c in container :
    title = c.select_one("h3.lister-item-header>a").text
    metascore = c.select_one(" div.ipl-rating-widget div.small > span.ipl-rating-star__rating")
    director = c.select("div.lister-item-content p:nth-of-type(3) a")
    genre = c.select_one("div.lister-item-content p:nth-of-type(1) span.genre")

    if "Action" not in genre.text:
        continue

    print("제목: ", title)

    if metascore is not None:
        print( "\n평점:", metascore.text.strip())
    else:
        print("\n평점이 없습니다.")
        #
        # print("평점: ", metascore.text)

    print("\n장르: ")
    for g in genre:
        print(g.strip())       #g는 .text 붙이면 에러뜸.

    print("\n감독 및 배우: ")
    for d in director:
        print(d.text)

    print("="*20)


import secrets

from starlette.background import BackgroundTask
from asyncpg.exceptions import UniqueViolationError
from starlette.responses import JSONResponse

from admin.audit_logs import send_audit_log, AuditColour
from admin.discord_api import get_user
from admin.route import Route
from admin.models import APIKey
from admin.utils import is_admin, is_authorized, is_json

class AdminUserRoute(Route):
    """
    Route for fetching and creating new users.
    """
    name = "all_users"
    path = "/users"

    @is_authorized
    @is_admin
    async def get(self, request):
        users = await APIKey.query.where(
            APIKey.creator.isnot(None)
        ).order_by(
            APIKey.is_admin.desc()
        ).gino.all()

        response = []

        for user in users:
            user_data = user.__dict__["__values__"]

            user_data["creator"] = str(user_data["creator"])

            response.append(user_data)

        return JSONResponse(response)

    @is_authorized
    @is_admin
    @is_json
    async def post(self, request):
        data = await request.json()

        try:
            get_user(int(data["creator"]))
        except KeyError:
            return JSONResponse({
                "status": "error",
                "message": "Invalid user specified, upstream returned 404"
            }, status_code=404)

        new_key = APIKey(
            key=secrets.token_hex(32),
            is_admin=data["is_admin"],
            creator=int(data["creator"])
        )

        try:
            await new_key.create()
        except UniqueViolationError:
            return JSONResponse({
                "status": "error",
                "message": "Users can only have one API key per Discord ID"
            }, status_code=400)

        task = BackgroundTask(
            send_audit_log,
            title="New user added",
            body=f"Added by <@{request.state.api_key.creator}>",
            inline_fields={
                "User": f"<@{data['creator']}>",
                "Administrator": data["is_admin"]
            },
            colour=AuditColour.SUCCESS
        )

        return JSONResponse({
            "status": "success",
            "new_key": new_key.key
        }, background=task)


from django.conf.urls import url,include
from django.contrib import admin
from. import views
urlpatterns=[
    url(r'^$',view=views.lb,name="logbook"),
    url(r'^login$',view=views.login,name="login"),
    url(r'^add$',view=views.add,name='add'),
    url(r'^view$',view=views.view,name='view'),
    url(r'^view/(?P<username>[A-Za-z0-9]+)$',view=views.viewbyusername,name='view'),
    url(r'^requestid$',view=views.requestid,name='requestid')

]


import dicom_reader
import con_reader
import con2img
import volume as vol
from matplotlib.pyplot import plot, imshow, show

def test_dicom_reader():

    path = "../data/Eredetikepek/1___AW1295938826.919.1531920932/2018-07-16_1.2.840.113619.2.181.60341967613.14520.1531920932966.2/"
    dc = dicom_reader.DCMreader(path)
    print("Reading was finished!")

    imshow(dc.get_image(2, 23))
    show()

#test_dicom_reader()

def test_con_reader():

    path = "../data/Kontur/Buday_Krisztina_20180712_sa_SER1001_ACQ10.con"
    cn = con_reader.CONreader(path)
    print("Reading was finished!")

    crs = cn.get_hierarchical_contours()
    x, y = crs[7][11][0]['x'], crs[7][11][0]['y']
    plot(x, y, 'ro')
    show()

#test_con_reader()

def test_con_volumedata():
    base_path = "../../data/SA_all_2/19307824AMR806/1301/"
    con_path = base_path + "contour.con"
    cn = con_reader.CONreader(con_path)
    fw, reso, width, weight, height = cn.get_volume_data()
    assert fw[0] == 329.999996 and fw[1] == 329.999996, 'Wrong field view!'
    assert reso[0] == 224 and reso[1] == 224, 'Wrong image resolution!'
    assert width == 8.0, 'Wrong sice width!'
    print('OK: test_con_volumedata')

#test_con_volumedata()

def test_con2img():
    base_path = "../../data/SA_all_2/19194862AMR806/1401/"
    #base_path = "../../data/SA_all_2/19307824AMR806/1301/"
    dcm_path = base_path + "imgs/"
    con_path = base_path + "contour.con"

    con2img.draw_contours2images(dcm_path, con_path)
    print("OK: test_con2img")

test_con2img()

def test_volume():
    path1 = "../../data/volume_test/Takacs_Akos_20180131_038318067_STD19194862AMR806_SER1401_ACQ14.con"
    path2 = "../../data/SA_all/17352962AMR801/901/contour.con"
    path4 = "../../data/SA_all/17577538AMR801/901/contour.con"
    path5 = "../../data/SA_all/17651351AMR806/1301/contour.con"
    path6 = "../../data/SA_all/17827245AMR809/1301/contour.con"

    v = vol.Volume(path6)
    v.calculate_volumes('pixel')
    print('---------------------------')
    print('LEFT VEN.')
    print('LVED: %.3f'%v.lved)
    print('LVED-idx: %.3f'%v.lved_i)
    print('LVES: %.3f'%v.lves)
    print('LVES-idx: %.3f'%v.lves_i)
    print('LVSV: %.3f'%v.lvsv)
    print('LVSV-idx: %.3f'%v.lvsv_i)

    print('---------------------------')
    print('RIGHT VEN.')
    print('RVED: %.3f'%v.rved)
    print('RVED-idx: %.3f'%v.rved_i)
    print('RVES: %.3f'%v.rves)
    print('RVES-idx: %.3f'%v.rves_i)
    print('RVSV: %.3f'%v.rvsv)
    print('RVSV-idx: %.3f'%v.rvsv_i)

#test_volume()