import re

# Inicialização da tabela de símbolos com palavras-chave
keyword_table = {
    'if': 'IF',
    'else': 'ELSE',
    'while': 'WHILE',
    'for': 'FOR',
    # adicione mais palavras-chave aqui, se necessário
}

# Expressões regulares para reconhecer tokens
decimal_pattern = r'\d+(\.\d+)?'
operator_pattern = r'[+\-*/]'
relational_operator_pattern = r'[<>]=?'
identifier_pattern = r'[a-zA-Z_][a-zA-Z0-9_]*'
resto = ['(', ')', '{', '}']
igual = ['=']

# Função para remover comentários da linguagem C
def remove_comments(line):
    # Remove comentários de bloco /* ... */
    line = re.sub(r'/\*.*?\*/', '', line)

    # Remove comentários de linha // ...
    line = re.sub(r'//.*', '', line)

    return line

# Função para realizar a análise léxica
def lex(input_string):
    tokens = []
    lines = input_string.split('\n')
    line_number = 1

    for line in lines:
        line = remove_comments(line)
        line = line.strip()  # Remove espaços em branco no início e no fim

        position = 0
        while position < len(line):
            token = None
            if line[position].isspace():
                position += 1
                continue

            if line[position] == ';':
                token = line[position]
                tokens.append(('SEMICOLON', token, line_number))
                position += 1
                continue

            if line[position] == '=':
                token = line[position]
                tokens.append(('Equal', token, line_number))

                position += 1
                continue

            # Reconhecimento de números decimais
            match = re.match(decimal_pattern, line[position:])
            if match:
                token = match.group(0)
                tokens.append(('NUM', token, line_number))
                position += len(token)
                continue

            # Reconhecimento de operadores aritméticos
            if line[position] in '+-*/':
                token = line[position]
                tokens.append(('OP_ARIT', token, line_number))
                position += 1
                continue

            # Reconhecimento de operadores relacionais
            match = re.match(relational_operator_pattern, line[position:])
            if match:
                token = match.group(0)
                tokens.append(('OP_REL', token, line_number))
                position += len(token)
                continue

            # Reconhecimento de identificadores
            match = re.match(identifier_pattern, line[position:])
            if match:
                token = match.group(0)

                # Verifica se é uma palavra-chave
                if token in keyword_table:
                    tokens.append((keyword_table[token], token, line_number))
                else:
                    tokens.append(('ID', token, line_number))

                position += len(token)
                continue

            # Se chegou até aqui, é um caractere inválido
            token = line[position]
            print(f"Erro: Caractere inválido '{token}' na linha {line_number}")
            position += 1

        line_number += 1

    return tokens

# Exemplo de uso
program = '''
int x = 10;
float y = 3.14; // teste
if x > y  /* aaaaaa */
    printf("x > y");
 else
    printf("x <= a y");

'''
tokens = lex(program)
for token in tokens:
    print(token)


import json
import redis

from redis import asyncio as aioredis
from redis.asyncio.client import Redis
from typing import Callable

from src.config import Config

async def redis_client():
    try:
        return await aioredis.from_url(
            f"redis://{Config.REDIS_HOST}:{Config.REDIS_PORT}",
            encoding="utf8", decode_responses=True
        )
    except redis.exceptions.ConnectionError as e:
        print("Connection error:", e)
    except Exception as e:
        print("An unexpected error occurred:", e)

async def listen_to_channel(filter_func: Callable, user_id: str, redis_conn: Redis):
    async with redis_conn.pubsub() as listener:
        await listener.subscribe(Config.PUSH_NOTIFICATIONS_CHANNEL)
        while True:
            message = await listener.get_message()
            if message is None:
                continue
            if message.get("type") == "message":
                message = json.loads(message["data"])
                if filter_func(user_id, message):
                    yield {"data": message}


#Para conexion del cliente
THIS_CLIENT_ID = "BACCHUS'S TORRCLIENT"
#THIS_CLIENT_ID= "FSTSEEDER TORRCLIENT"
PORT = 9200
MAX_UPLOAD_PEERS = 4

#Constantes de bloques y piezas
DEF_BLOCK_LENGTH = 16384
DEF_PIECE_LENGTH = 524288


import time

"""
Secuencia de Fibonacci

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

1  2  3  4  5  6  7   8   9   10  11   12   13

fibonacci(x) =
  Si x es 1 o 2 entonces el resultado es 1
  En otro el resultado es la suma de los dos anteriores

fibonacci(1) = 1
fibonacci(2) = 1
fibonacci(x) = fibonacci(x - 1) + fibonacci(x - 2)
"""

def optimizacion(fibo):
  memoria = {}

  def fibo_optimizado(x):
    if x not in memoria:
      memoria[x] = fibo(x)
    return memoria[x]

  return fibo_optimizado

@optimizacion
def fibo(x):
  if x == 1 or x == 2:
    return 1

  return fibo(x - 1) + fibo(x - 2)

start_time = time.time() # Tomando el tiempo inicial

print("fibo(500) =", fibo(500))

end_time = time.time() # Tomando el tiempo final

segundos = end_time - start_time

print("El algoritmo tardo {} segundos".format(segundos))


#You can delete this file
import os, sys, inspect
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parent_dir = os.path.dirname(current_dir)
src_dir = os.path.join (parent_dir, "src")
sys.path.insert(0,src_dir)

import pytest
from person_oop_module import Person

def test_person_initializer_validate_name():
    p1 = Person("John", 36)
    assert p1.name == 'John'


##!/usr/bin/env python
'''
    @author [mst]
    @brief  leetcode problems series
    518_coin_change2
    You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
    Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.

    Constraints:
    1 <= coins.length <= 300
    1 <= coins[i] <= 5000
    All the values of coins are unique.
    0 <= amount <= 5000

    gains:
    -dynamic programming: bottom -up permutations counting

    @version 2023.02
'''

################## DECL_IMPL

class Solution:
    def change(self, n, c):
        n_perms = [1]+[0]*n
        for coin in c:
            for i in range(coin, n+1):
                n_perms[i] += n_perms[i-coin]
        return n_perms[n]

################## DRIVER
def main():
    sol = Solution()

    # testing
    n,c = 500, [1,2,5]
    print (sol.change(n, c)
)

if __name__ == ("__main__"):
    main()


'''
for in em python
Iterando strings com python
função range(start = 0, stop = 0, step = 1)
'''

# revisando while
texto = 'Python'
c = 0
while c < len(texto):
    print(texto[c])
    c += 1

print('-'*15)
texto = 'Python'
for letra in texto:
    print(letra)

print('-'*15)
texto = 'Python'
for n, letra in enumerate(texto):
    print(n, letra)

print('-'*15)
for n in range(5, 51, 2):
    print(n)

print('-'*15)
for n in range(50):
    if n % 5 == 0:
        print(n)

print('-'*15)
# continue - pula para o próximo laço
# break - termina o laço
texto = 'Python, Python'
nova_string = ''
for letra in texto:
    if letra == 't':
        #continue
        nova_string = nova_string + letra.upper()
    elif letra == 'h':
        nova_string += letra.upper()
        #break
    else:
        nova_string += letra
print(nova_string)


import dataclasses
import functools
import re
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union

import jax
from jax import numpy as jnp
import optax

JTensor = Any
NestedJTensor = Any
NestedHParams = Any

def to_quantized(fvalue: JTensor,
                 quantized_dtype: jnp.dtype) -> Tuple[JTensor, JTensor]:
  """Converts floating point values `fvalues` to quantized values.

  We use a very simple quantization scheme where the range is symmetric around
  0.0, and we simply map 0 to 0.0.

  Let x = bucket_size
  We map [-0.5x, 0.5x] to 0
         [-1.5x, -0.5x] to -1
         [0.5x, 1.5x] to 1
         and so on so forth.

  Some properties:
    a1, a2 = to_quantized(x, quantized_dtype)
    b1 = to_float(a1, a2)
    c1, c2 = to_quantized(b1, quantized_dtype)

    then a1 == c1, a2 == c2

  Args:
    fvalue: Values in floating point.
    quantized_dtype: Quantized dtype, can be either jnp.int8, or jnp.int16.

  Returns:
    A (quantized_values, bucket_size) 2-tuple.
    `quantized_values * bucket_size[jnp.newaxis, ...]` are the quantized
    values
    on the floating value axis.
  """
  float_dtype = fvalue.dtype
  if quantized_dtype == jnp.int8:
    # value -128 is not used.
    num_buckets = jnp.array(127.0, dtype=float_dtype)
  elif quantized_dtype == jnp.int16:
    # value -32768 is not used.
    num_buckets = jnp.array(32767.0, dtype=float_dtype)
  else:
    raise ValueError(f'Quantized dtype {quantized_dtype} not supported.')
  # max value is mapped to num_buckets

  # We first decide the scale.
  if fvalue.ndim < 1:
    raise ValueError(
        f'Input array {fvalue} must have a strictly positive number of '
        'dimensions.')

  max_abs = jnp.max(jnp.abs(fvalue), axis=0)
  bucket_size = max_abs / num_buckets
  bs_expanded = bucket_size[jnp.newaxis, ...]
  # To avoid divide by 0.0
  bs_nonzero = jnp.where(bs_expanded > 0.0,
                         bs_expanded,
                         jnp.ones_like(bs_expanded))
  ratio = fvalue / bs_nonzero
  # We use rounding to remove bias.
  quantized = jnp.round(ratio)
  return quantized.astype(quantized_dtype), bucket_size

def to_float(quantized: JTensor, bucket_size: JTensor) -> JTensor:
  """Converts quantized values to float values.

  Args:
    quantized: Quantized values, of type either jnp.int8 or jnp.int16.
    bucket_size: The size of each bucket on the floating-point axis. bucket_size
      is of rank tf.rank(quantized) - 1. For example, if quantized is of shape
      [x, ...], bucket_size is of shape [...].

  Returns:
    Unquantized values of type bucket_size.dtype.
  """
  float_dtype = bucket_size.dtype
  bucket_size = bucket_size[jnp.newaxis, ...]
  return quantized.astype(float_dtype) * bucket_size

def adafactor_decay_rate_adam(beta2: float, step_counter: JTensor) -> JTensor:
  """Second-moment decay rate like Adam, subsuming the correction factor.

  Args:
    beta2: A floating point value between 0 and 1.
    step_counter: A scalar tensor keeping track of the number of steps
      performed.

  Returns:
    The decay rate as a scalar JTensor.
  """
  step = step_counter
  beta2 = jnp.array(beta2, dtype=jnp.float32)
  t = step + 1.
  return beta2 * (1. - jnp.power(beta2, t - 1.)) / (1. - jnp.power(beta2, t))

def adafactor_decay_rate_pow(exponent: float, step_counter: JTensor) -> JTensor:
  """Second moment decay rate where memory-length grows as step_num^exponent.

  Args:
    exponent: A floating point value between 0 and 1.
    step_counter: A scalar tensor keeping track of the number of steps
      performed.

  Returns:
    The decay rate as a scalar JTensor.
  """
  step = step_counter
  exponent = jnp.array(exponent, dtype=jnp.float32)
  return 1. - jnp.power((step + 1.), -exponent)

def reduce_mean(array: JTensor) -> JTensor:
  """Computes the mean of `array` in a more numerically stable way.

  Args:
    array: Input array.

  Returns:
    The mean of the input array as a scalar array.
  """
  num_elements = array.size
  if num_elements > 1e8:
    # When x is too large, simple jnp.mean() can result in nan or inf values.
    # TODO(bf-jax): The following code snippet is consistent with the TensorFlow
    # implementation. This can be simplified into `jnp.mean(jnp.mean(x, -1))`.
    # Update to using mean() after verifying consistency.
    array_sum = jnp.sum(array, axis=-1)
    array_sum = jnp.sum(array_sum)
    return array_sum / jnp.array(num_elements, dtype=array_sum.dtype)
  else:
    return jnp.mean(array)

def reduce_rms(array: JTensor) -> JTensor:
  """Computes the RMS of `array` (in a numerically stable way).

  Args:
    array: Input array.

  Returns:
    The root mean square of the input array as a scalar array.
  """
  sq = jnp.square(array)
  sq_mean = reduce_mean(sq)
  return jnp.sqrt(sq_mean)

@dataclasses.dataclass(frozen=True)
class _ShardedAdafactorUpdateResult:
  """Structure containing per-variable info for Adafactor."""
  update: Optional[Any]
  m: Optional[Any]
  m_scale: Optional[Any]
  vr: Optional[Any]
  vc: Optional[Any]
  v: Optional[Any]

class ShardedAdafactorState(NamedTuple):
  """Overall state of the ShardedAdafactor optimizer."""
  count: JTensor
  m: Optional[NestedJTensor]
  m_scale: Optional[NestedJTensor]
  vr: Optional[NestedJTensor]
  vc: Optional[NestedJTensor]
  v: Optional[NestedJTensor]

class _ShardedAdafactorHelper:
  """Helper class to implement optax-based sharded Adafactor."""

  def __init__(self,
               learning_rate: optax.Schedule,
               weight_decay: Optional[float],
               layerwise_adaptation: bool,
               decay_method: str,
               decay_adam: float,
               decay_pow: float,
               beta1: float,
               clip_threshold: Optional[float],
               factored: bool,
               epsilon1_grad_sq_reg: float,
               quantized_dtype: jnp.dtype,
               respect_skip_lp_regularization: bool,
               exclude_from_layerwise_adaptation: Optional[List[str]],
               per_var_learning_summary: bool,
               sort_factored_second_moment_dims: bool,
               min_dim_size_to_factor: int,
               multiply_by_parameter_scale: bool,
               epsilon2_param_scale_reg: float,
               maybe_inf_to_nan: bool,
               nesterov: bool) -> None:
    """Constructor. See ShardedAdafactor() below."""

    self._learning_rate = learning_rate
    self._weight_decay = weight_decay
    self._layerwise_adaptation = layerwise_adaptation
    self._decay_method = decay_method
    self._decay_adam = decay_adam
    self._decay_pow = decay_pow
    self._beta1 = beta1
    self._clip_threshold = clip_threshold
    self._factored = factored
    self._epsilon1 = epsilon1_grad_sq_reg
    self._quantized_dtype = quantized_dtype
    self._respect_skip_lp_regularization = respect_skip_lp_regularization
    self._exclude_from_layerwise_adaptation = exclude_from_layerwise_adaptation
    self._per_var_learning_summary = per_var_learning_summary
    self._sort_factored_second_moment_dims = sort_factored_second_moment_dims
    self._min_dim_size_to_factor = min_dim_size_to_factor
    self._multiply_by_parameter_scale = multiply_by_parameter_scale
    self._epsilon2 = epsilon2_param_scale_reg
    self._maybe_inf_to_nan = maybe_inf_to_nan
    self._nesterov = nesterov

  def should_use_factored_second_moment_estimate(self, shape):
    """Should we use a factored second moment estimator.

    Based on the shape of the variable.

    Args:
      shape: a list of integers.

    Returns:
      A boolean.
    """
    return self.factored_second_moment_dims(shape) is not None

  def factored_second_moment_dims(self, shape):
    """Should we use a factored second moment estimator.

    We select largest and second largest var dims as row and colum dims.

    Default list of factored dims is -1, -2.

    Args:
      shape: a list of integers.

    Returns:
      either a list of 2 Dimension indices for row and col or None
    """
    if not self._factored:
      return None
    if len(shape) < 2:
      return None
    if not self._sort_factored_second_moment_dims:
      return len(shape) - 1, len(shape) - 2

    def largest_two_dim_indices():
      s = [(s, i) for i, s in enumerate(shape)]
      sorted_dims = sorted(s, key=lambda d: -d[0])
      return sorted_dims[0][1], sorted_dims[1][1]

    r_idx, c_idx = largest_two_dim_indices()
    if shape[c_idx] < self._min_dim_size_to_factor:
      return None
    return r_idx, c_idx

  def should_store_momentum_in_qint(self, shape):
    """Should we store momentum as quantized integers.

    Based on the shape of the variable.

    Args:
      shape: a list of integers

    Returns:
      A boolean.
    """
    if jnp.issubdtype(self._quantized_dtype, jnp.floating):
      return False
    if self._quantized_dtype is None:
      return False
    return len(shape) >= 1

  def to_state(self, count, result_tree):
    """Maps from a tree of (factored) values to separate trees of values."""
    return ShardedAdafactorState(
        count=count,
        m=jax.tree_map(lambda o: o.m, result_tree),
        m_scale=jax.tree_map(lambda o: o.m_scale, result_tree),
        vr=jax.tree_map(lambda o: o.vr, result_tree),
        vc=jax.tree_map(lambda o: o.vc, result_tree),
        v=jax.tree_map(lambda o: o.v, result_tree))

  def init(self, param):
    """Initializes the optimizer state for a given param."""
    # The actually value that will be added to a variable for updating it.
    output_update = jnp.zeros((1,))
    output_m = jnp.zeros((1,))
    output_m_scale = jnp.zeros((1,))
    output_vr = jnp.zeros((1,))
    output_vc = jnp.zeros((1,))
    output_v = jnp.zeros((1,))
    shape = param.shape
    if self._beta1:
      if jnp.issubdtype(self._quantized_dtype, jnp.floating):
        output_m = jnp.zeros(shape, dtype=self._quantized_dtype)
      elif self.should_store_momentum_in_qint(shape):
        output_m = jnp.zeros(shape, dtype=self._quantized_dtype)
        scale_shape = shape[1:]
        output_m_scale = jnp.zeros(scale_shape, dtype=jnp.float32)
      else:
        output_m = jnp.zeros(shape, dtype=jnp.float32)
    if self.should_use_factored_second_moment_estimate(shape):
      factored_dims = self.factored_second_moment_dims(shape)
      vr_axis, vc_axis = factored_dims
      output_vr_shape = list(shape).copy()
      del output_vr_shape[vr_axis]
      output_vc_shape = list(shape).copy()
      del output_vc_shape[vc_axis]
      output_vr = jnp.zeros(output_vr_shape, dtype=jnp.float32)
      output_vc = jnp.zeros(output_vc_shape, dtype=jnp.float32)
    else:
      output_v = jnp.zeros(shape, dtype=jnp.float32)
    return _ShardedAdafactorUpdateResult(
        update=output_update,
        m=output_m,
        m_scale=output_m_scale,
        vr=output_vr,
        vc=output_vc,
        v=output_v)

  def inf_to_nan(self, array):
    """Converting Infinity values to the more sticky NaN."""
    # For example, when we have y = 1.0 / x in code and x == inf, y will become
    # 0. Therefore the infinite value of x is hidden in the calculation,
    # leading to silent omission of numerical issues.
    if not self._maybe_inf_to_nan:
      return array
    return jnp.nan_to_num(array, nan=jnp.nan, posinf=jnp.nan, neginf=jnp.nan)

  def parameter_scale(self, var):
    """Estimate the scale of the parameters from the current values.

    We include a minimum value of 0.001 to give it a chance to escape 0
    if it was zero-initialized.

    Instead of using the value, we could impute the scale from the shape,
    as initializers do.

    Args:
      var: a variable or Tensor.

    Returns:
      a Scalar
    """
    return jnp.maximum(reduce_rms(var), jnp.asarray(self._epsilon2, var.dtype))

  def compute_var_and_slot_update(self,
                                  count,
                                  grad,
                                  m,
                                  m_scale,
                                  vr,
                                  vc,
                                  v,
                                  param,
                                  var_name=None):
    """Computes the var and optimizer slots updates for a single variable."""
    # We can probably skip this step
    grad = grad.astype(jnp.float32)
    grad = self.inf_to_nan(grad)
    grad_squared = jnp.square(grad)

    # Add epsilon1_grad_sq_reg as per Algorithm 4
    # of https://arxiv.org/pdf/1804.04235.pdf
    grad_squared += self._epsilon1
    grad_squared_mean = self.inf_to_nan(reduce_mean(grad_squared))
    if self._decay_method == 'adam':
      assert self._decay_adam > 0
      decay_rate = adafactor_decay_rate_adam(self._decay_adam, count)
    elif self._decay_method == 'pow':
      assert self._decay_pow > 0
      decay_rate = adafactor_decay_rate_pow(self._decay_pow, count)
    else:
      raise ValueError(f'decay_method {self._decay_method} not supported.')

    learning_rate = self._learning_rate
    if callable(learning_rate):
      learning_rate = learning_rate(count)

    update_scale = learning_rate
    old_val = param

    if self._multiply_by_parameter_scale:
      update_scale *= self.parameter_scale(old_val).astype(update_scale.dtype)

    # Q(yonghui): Can we remove the hack now?
    # HACK: Make things dependent on grad.
    # This confounds the XLA rewriter and keeps it from fusing computations
    # across different variables.  This fusion is a bad for HBM usage, since
    # it causes the gradients to persist in memory.
    decay_rate += grad_squared_mean * 1e-30
    update_scale += grad_squared_mean * 1e-30
    # END HACK

    mixing_rate = 1. - decay_rate
    shape = param.shape

    output_m = jnp.zeros((1,))
    output_m_scale = jnp.zeros((1,))
    output_vr = jnp.zeros((1,))
    output_vc = jnp.zeros((1,))
    output_v = jnp.zeros((1,))

    factored_second_moment_dims = self.factored_second_moment_dims(shape)
    if factored_second_moment_dims is not None:
      # Q(shafey): Should we use the more numerically stable version
      # reduce_mean().
      vr_axis, vc_axis = factored_second_moment_dims
      grad_squared_row_mean = self.inf_to_nan(
          jnp.mean(grad_squared, axis=vr_axis))
      grad_squared_col_mean = self.inf_to_nan(
          jnp.mean(grad_squared, axis=vc_axis))
      new_vr = decay_rate * vr + mixing_rate * grad_squared_row_mean
      new_vc = decay_rate * vc + mixing_rate * grad_squared_col_mean
      output_vr = new_vr
      output_vc = new_vc
      long_term_mean = jnp.mean(new_vr, axis=-1, keepdims=True)
      r_factor = 1. / jnp.sqrt(new_vr / long_term_mean)
      c_factor = 1. / jnp.sqrt(new_vc)
      x = grad * jnp.expand_dims(r_factor, vr_axis) * jnp.expand_dims(
          c_factor, vc_axis)
    else:
      # v with sharding annotation.
      new_v = decay_rate * v + mixing_rate * grad_squared
      output_v = new_v
      x = grad / jnp.sqrt(new_v)

    if self._clip_threshold is not None:
      clipping_denom = jnp.maximum(1., reduce_rms(x) / self._clip_threshold)
      clipping_denom = self.inf_to_nan(clipping_denom)
      x /= clipping_denom

    subtrahend = update_scale * x
    if self._beta1:
      if jnp.issubdtype(self._quantized_dtype, jnp.floating):
        m = m.astype(jnp.float32)
      elif self.should_store_momentum_in_qint(shape):
        m_init_dtype = m.dtype
        m = to_float(m, m_scale)
      if self._nesterov:
        subtrahend_original = subtrahend
      subtrahend = self._beta1 * m + (1. - self._beta1) * subtrahend
      subtrahend = self.inf_to_nan(subtrahend)
      if self._quantized_dtype == jnp.bfloat16:
        new_m = subtrahend.astype(jnp.bfloat16)
        output_m = new_m
      elif self.should_store_momentum_in_qint(shape):
        # Update the momentum values.
        new_m_val, new_m_scale = to_quantized(subtrahend, m_init_dtype)
        output_m = new_m_val
        output_m_scale = new_m_scale
      else:
        output_m = subtrahend

      if self._nesterov:
        subtrahend = (
            self._beta1 * subtrahend +
            (1.0 - self._beta1) * subtrahend_original)

    if self._weight_decay is not None:
      # Apply decoupled weight decay to be consistent with AdamW.
      var_weight_decay = None
      if isinstance(self._weight_decay, dict):
        for scope_pattern in self._weight_decay.keys():
          regex_pattern = re.compile(scope_pattern)
          if regex_pattern.match(var_name):
            var_weight_decay = self._weight_decay[scope_pattern]
      else:
        var_weight_decay = self._weight_decay

      if var_weight_decay is not None:
        weight_decay = var_weight_decay * learning_rate
        subtrahend += weight_decay * old_val

    if self._layerwise_adaptation:
      include = True
      if self._exclude_from_layerwise_adaptation is not None:
        for scope_pattern in self._exclude_from_layerwise_adaptation:
          regex_pattern = re.compile(scope_pattern)
          if regex_pattern.match(var_name):
            include = False
            break
      if include:
        w_norm = reduce_rms(old_val)
        g_norm = reduce_rms(subtrahend / update_scale) + self._epsilon1
        ratio = w_norm / g_norm
        ratio = jnp.where(
            jnp.greater(w_norm, 0),
            jnp.where(jnp.greater(g_norm, 0), (w_norm / g_norm), 1.0),
            1.0)
        subtrahend *= ratio

    return _ShardedAdafactorUpdateResult(
        update=-subtrahend,
        m=output_m,
        m_scale=output_m_scale,
        vr=output_vr,
        vc=output_vc,
        v=output_v)

def sharded_adafactor(
    learning_rate: optax.Schedule,
    weight_decay: Optional[Union[float, Dict[str, float]]] = None,
    layerwise_adaptation: bool = False,
    decay_method: str = 'adam',
    decay_adam: float = 0.99,
    decay_pow: float = 0.,
    beta1: float = 0.9,
    clip_threshold: Optional[float] = 1.,
    factored: bool = True,
    epsilon1_grad_sq_reg: float = 1e-30,
    quantized_dtype: jnp.dtype = jnp.int8,
    respect_skip_lp_regularization: bool = False,
    exclude_from_layerwise_adaptation: Optional[List[str]] = None,
    per_var_learning_summary: bool = False,
    sort_factored_second_moment_dims: bool = False,
    # min_dim_size_to_factor is only used when
    # sort_factored_second_moment_dims=True.
    min_dim_size_to_factor: int = 128,
    multiply_by_parameter_scale: bool = False,
    epsilon2_param_scale_reg: float = 1e-3,
    maybe_inf_to_nan: bool = True,
    nesterov: bool = False,
) -> optax.GradientTransformation:
  """AdaFactor optimizer that supports SPMD sharding.

  Reference:
    Shazeer et al, 2018: https://arxiv.org/abs/1804.04235

  Adafactor is very similar to Adam (Kingma and Ba, 2019), the major
  differences being:

  1. For a two-dimensional AxB weight matrix, Adafactor uses only A+B auxiliary
     parameters to maintain the second-moment estimator, instead of AB.
     This is advantageous on memory-limited systems.  In addition, beta1
     (momentum) is set to zero by default, saving an additional auxiliary
     parameter per weight.  Variables with >=3 dimensions are treated as
     collections of two-dimensional matrices - factorization is over the final
     two dimensions.

  2. Adafactor incorporates "update-clipping" - a scale-invariant analog of
     gradient clipping.  This improves stability.

  3. Adafactor does not require an external "learning rate".  By default, it
     incorporates a relative-update-scale schedule, corresponding to
     inverse-square-root learning-rate-decay in Adam.  We hope this works well
     for most applications.

  Args:
    learning_rate: a callable that given the current training step, returns the
      learning rate to apply.
    weight_decay: an optional float tensor as decoupled weight decay value, or a
      dictionary with key as regex scope pattern and value as corresponding
      weight decay float tensor. The value will apply to all variables under
      that scope name.
    layerwise_adaptation: a boolean, whether or not to use layer-wise adaptive
      moments (LAMB) https://arxiv.org/abs/1904.00962.
    decay_method: a string, deciding how decay_rate should be computed.
      Permitted values are 'adam' and 'pow'.
    decay_adam: a float, decay if decay_method == 'adam'.
    decay_pow: a float, decay if decay_method == 'pow'.
    beta1: a float value between 0 and 1 for momentum.
    clip_threshold: an optional float >= 1
    factored: a boolean, whether or not to use factored second order momentum.
    epsilon1_grad_sq_reg: Regularization constant for squared gradient.
    quantized_dtype: type of the quantized input. Allowed options are jnp.int8,
      jnp.int16, jnp.bfloat16 and jnp.float32. If floating-point type is
      specified, accumulators are stored as such type, instead of quantized
      integers.
    respect_skip_lp_regularization: whether or not to respect lingvo
      SKIP_LP_REGULARIZATION var collection that skips decoupled weight decay.
    exclude_from_layerwise_adaptation: A dictionary with key as regex scope
      pattern for variables to be skipped.
    per_var_learning_summary: a bool, whether or not to export per-var learning
      summaries.
    sort_factored_second_moment_dims: a bool, whether to select dims to factor
      by size, for the factored second moment.
    min_dim_size_to_factor: an integer, only factor the statistics if two array
      dimensions have at least this size. NOTE min_dim_size_to_factor is only
      used when sort_factored_second_moment_dims=True.
    multiply_by_parameter_scale: a boolean, if True, then scale learning_rate by
      parameter scale. if False provided learning_rate is absolute step size.
      NOTE False by default.
    epsilon2_param_scale_reg: Regularization constant for parameter scale. Only
      used when multiply_by_parameter_scale is True.
    maybe_inf_to_nan: Will use jax.nan_to_num during update when True.
    nesterov: Will use Nesterov momentum when True.

  Returns:
    A `ShardedGradientTransformation`.
  """

  assert not respect_skip_lp_regularization
  assert decay_adam >= 0
  assert decay_pow >= 0
  assert learning_rate is not None
  assert decay_method == 'adam' or decay_method == 'pow', (
      f'decay_method: {decay_method} not supported. Supported methods are '
      '"pow", or "adam".')

  sharded_adafactor_helper = _ShardedAdafactorHelper(
      learning_rate=learning_rate,
      weight_decay=weight_decay,
      layerwise_adaptation=layerwise_adaptation,
      decay_method=decay_method,
      decay_adam=decay_adam,
      decay_pow=decay_pow,
      beta1=beta1,
      clip_threshold=clip_threshold,
      factored=factored,
      epsilon1_grad_sq_reg=epsilon1_grad_sq_reg,
      quantized_dtype=quantized_dtype,
      respect_skip_lp_regularization=respect_skip_lp_regularization,
      exclude_from_layerwise_adaptation=exclude_from_layerwise_adaptation,
      per_var_learning_summary=per_var_learning_summary,
      sort_factored_second_moment_dims=sort_factored_second_moment_dims,
      min_dim_size_to_factor=min_dim_size_to_factor,
      multiply_by_parameter_scale=multiply_by_parameter_scale,
      epsilon2_param_scale_reg=epsilon2_param_scale_reg,
      maybe_inf_to_nan=maybe_inf_to_nan,
      nesterov=nesterov)

  def init_fn(params):
    """Initializes the optimizer's state."""
    return sharded_adafactor_helper.to_state(
        jnp.zeros([], jnp.int32),
        jax.tree_map(sharded_adafactor_helper.init, params))

  def update_fn(updates, state, params=None):
    if params is None:
      raise ValueError(
          'You are using a transformation that requires the current value of '
          'parameters, but you are not passing `params` when calling `update`.')

    compute_var_and_slot_update_fn = functools.partial(
        sharded_adafactor_helper.compute_var_and_slot_update, state.count)
    output = jax.tree_map(compute_var_and_slot_update_fn,
                          updates,
                          state.m,
                          state.m_scale,
                          state.vr,
                          state.vc,
                          state.v,
                          params)
    updates = jax.tree_map(lambda o: o.update, output)
    count_plus_one = state.count + jnp.array(1, jnp.int32)
    updated_states = sharded_adafactor_helper.to_state(count_plus_one, output)
    return updates, updated_states

  return optax.GradientTransformation(init=init_fn, update=update_fn)


from requests import request

from .api_map import _API_MAP

from .exceptions import BadRequest, ResourceNotFound

class Api:
    def __init__(self):
        self.base_endpoint = _API_MAP['current']['api_root']

    def request(self, url, api_key, method, **kwargs):
        """
        Request structure
        """
        complete_url = '{}{}'.format(self.base_endpoint, url)
        header = {'TRN-Api-Key': api_key}
        response = request(method=method, url=complete_url, headers=header)
        return self.handle_response(response)

    def handle_response(self, response):
        """
        Evaluate response status code
        """
        status_code = response.status_code
        if 200 <= status_code <= 299:
            return response
        elif status_code == 400:
            raise BadRequest
        elif status_code == 404:
            raise ResourceNotFound


from tensorflow import keras
import numpy as np

"""
predict and parse output of dnn model.

input data is a len = 10 + 1 list or array of states
string (like "00", "01", ..)
"""

# Encode measurements outcomes
def parse_input(data):
    out_data = []
    states = ["00", "01", "10","11"]
    for me in data[0].split(" ")[::-1]:
        out_data.append(states.index(str(me)))

    return out_data

# Predict sample
def dnn_predict(model, sample):

    sample = parse_input(sample)
    pred = model.predict(sample)
    cat_pred = np.zeros_like(pred)
    for n,p in enumerate(pred):
        cat_pred[n,:] = [min(round(i), 4) for i in p]

    outputs = parse_output(cat_pred)
    return outputs

def parse_output(output):
    """
    Apply the transformation from the encoded error
    landscape to the full error landscape

    Parameters
    ----------
    output : array-like
        Output of the neural network model
    """
    err_lands = []
    output = np.array(output, dtype=int)
    for out in output:
        error_landscape = np.zeros( (4, 10) )
        for dt, qub in enumerate(out):
            if qub !=0:
                error_landscape[qub-1, dt] = 1

        err_lands.append(error_landscape)

    return err_lands


# -*- coding: utf-8 -*-

"""
Created on Wed Apr 25 15:32:00 2018

@author: augus
"""
# Lecture des fichiers texte en CSV

# importer les modules
import csv, math, numpy, re
from scipy import interpolate
from scipy.interpolate import interp1d, interp2d, griddata, Rbf
#from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
from Read_Thickness_Data import get_thickness_data
from mpl_toolkits.mplot3d.axes3d import Axes3D

#WT='NREL_5MW'
#WT='DTU_10MW'

""" Function to Extract Aerofoil data """
def Make_AirFoils_Profile(tab,WT):
    AirFoils_Profile=[]
    for i in range(len(tab)):

        if 'DTU_10MW' in WT:
            if 'F' in tab[i][0] or 'Cyl' in tab[i][0]:
                #print tab[i][0]
                AirFoils_Profile.append(tab[i][0])
                #print AirFoils_Profile
        if 'NREL_5MW' in WT:
            if 'NACA' in tab[i][0] or 'Round' in tab[i][0] or 'DU' in tab[i][0] :
                #print tab[i][0]
                if len(tab[i][0])>1:
                    AirFoils_Profile.append(tab[i][0])
                #print AirFoils_Profile
    #print AirFoils_Profile
    #print len(AirFoils_Profile)
    return AirFoils_Profile

""" Function to Extract Aerofoil data """
def get_aerofoils_data(WT):
    """ Function to extract AeroCoeff data
    Input:
        WT: Name of the choosen Wind Turbine
        AirFoil_Profile: list of char containing names for all profiles for this Wind Turbine
    Output:
        Profiles_DATA: list of list of aerocoeff for each profiles
    """
    fichier = 'WT_data/'+WT+'/Rwt.pro'
    f = open(fichier, "rb")
    fichier_csv = csv.reader(f, delimiter=" ")
    tab = list(fichier_csv)
    ###########
    AirFoil_Profile=Make_AirFoils_Profile(tab,WT)
    ###########
    Profiles_DATA=[]
    k=0
    index=-1
    profil_data=[]

    for i in range(len(tab)):
        #print k
        for profil in AirFoil_Profile:
            if profil in tab[i][0] and k!=0:
                #print str(i) + "  out"
                #print tab[i]+['out']

                k=0
                Profiles_DATA.append(profil_data)#=Profiles_DATA+[profil_data]
        if k==1:
            #print 'i= '+str(i)
            L=[]
            for c in tab[i]:
                x = re.findall(r"[-+]?\d*\.\d+|\d+", c)
                #print x
                if x != []:
                    L = L + x
            profil_data=profil_data+[L]

        for profil in AirFoil_Profile:
            if profil in tab[i][0]:
                #print str(i) + "  in"
                #print tab[i]
                k=1
                index=index+1
                profil_data=[]
    Profiles_DATA.append(profil_data) #Add the last Profile Data

    #print Profiles_DATA[0][:][0]
    #print len(Profiles_DATA[:])
    f.close()
    return Profiles_DATA[:]

#########TEST######
#AirFoil_Profile=['NACA64','DU21','DU25','DU30','DU35','DU40','Round']
#WT='NREL_5MW'
#print len(get_aerofoils_data(WT,AirFoil_Profile))
########################################################################################################################
""" Function to convert char data from get_aerofoils_data to floatting values"""
def CharToFloat(AeroChar):
    """
    Function to convert char data from get_aerofoils_data to floatting values
    :param AeroChar: containing char
    :return: AeroChar: containing float
    """

    for i0 in range(len(AeroChar)):
        for i1 in range(len(AeroChar[i0])):
            for i2 in range(len(AeroChar[i0][i1])):
                AeroChar[i0][i1][i2]=float(AeroChar[i0][i1][i2])
    return AeroChar

##############TEST#######################
#AirFoil_Profile=['NACA64','DU21','DU25','DU30','DU35','DU40','Round']
#WT='NREL_5MW'
#print CharToFloat(get_aerofoils_data(WT,AirFoil_Profile))

########################################################################################################################
""" Function to organize the data"""
def Organize_data_V2(Aerofoils_Data,Thickness):
    """
    Create a aero matrix (number_of_profile*number_of_data_per_profil,4), (Thickness ,Alpha, Cl, Cd)

    :param Aerofoils_Data: Data under list format
    :param Thickness: list format
    :return: Matrix Aero
    """
    #determins the dim of data:
    L=[]
    for i in range(len(Aerofoils_Data)):
        for k in range(len(Aerofoils_Data[i])):
            Aerofoils_Data[i][k]=[Thickness[i]]+Aerofoils_Data[i][k]
            L.append(Aerofoils_Data[i][k])
    #print L
    #print len(L)
    New_Aerofoils_Data_mat=numpy.zeros((len(L),4))
    for i in range(len(L)):
        New_Aerofoils_Data_mat[i, 0] = L[i][0]   # Thickness
        New_Aerofoils_Data_mat[i, 1] = L[i][1]   # Angular
        New_Aerofoils_Data_mat[i, 2] = L[i][2]   # Cl
        New_Aerofoils_Data_mat[i, 3] = L[i][3]   # Cd
    #print New_Aerofoils_Data_mat
    return New_Aerofoils_Data_mat

def Organize_data_V3(Aerofoils_Data,Thickness):
    """
    Create a aero matrix (number_of_profile*number_of_data_per_profil,4), (Thickness ,Alpha, Cl, Cd)
    +
    Include the thickness = 0 data, i.e: Cl=Cd=0
    :param Aerofoils_Data: Data under list format
    :param Thickness: list format
    :return: Matrix Aero
    """
    L=[]
    for i in range(len(Aerofoils_Data)):
        for k in range(len(Aerofoils_Data[i])):
            Aerofoils_Data[i][k]=[Thickness[i]]+Aerofoils_Data[i][k]
            L.append(Aerofoils_Data[i][k])
    #print L
    #print len(L)
    New_Aerofoils_Data_mat=numpy.zeros((len(L),4))
    for i in range(len(L)):
        New_Aerofoils_Data_mat[i, 0] = L[i][0]   # Thickness
        New_Aerofoils_Data_mat[i, 1] = L[i][1]   # Angular
        New_Aerofoils_Data_mat[i, 2] = L[i][2]   # Cl
        New_Aerofoils_Data_mat[i, 3] = L[i][3]   # Cd

    # create a matrix wich represent the data at thickness=0.
    lenght_0_matrix=len(Aerofoils_Data[0])
    zeros_matrix=numpy.zeros((lenght_0_matrix,4))
    for k in range(lenght_0_matrix):
        zeros_matrix[k,1]=L[k][1]

    # Concatenate the two matrix
    New_Aerofoils_Data_mat=numpy.concatenate((zeros_matrix,New_Aerofoils_Data_mat))

    #print New_Aerofoils_Data_mat
    return New_Aerofoils_Data_mat

#############TEST#############
#WT='NREL_5MW'
#result=Organize_data_V2(CharToFloat(get_aerofoils_data(WT)),get_thickness_data(WT))
#print result
#print len(result)
#print len(result[0])

########################################################################################################################

def interpolation2d_aerofoil_data(Aero_Mat):
    """
        Function returning for a value of an angle the list (Cl,Cd) interpolate for this angle
        :param profile_index: Index of Profile Number (Exemple for NREL_5MW):
            NACA64: 0
            DU21:   1
            DU25:   2
            DU30:   3
            DU35:   4
            DU40:   5
            Round:  6
        :param alpha: angle of attack in degree
        :return: list Cl,Cd interpolate for this angle
        """
    ALPHA=Aero_Mat[:,1]
    THICKNESS=Aero_Mat[:,0]
    CL=Aero_Mat[:,2]
    CD=Aero_Mat[:,3]

    xi = THICKNESS
    yi = ALPHA
    zi1 = CL
    zi2 = CD

    f1 = interp2d(xi, yi, zi1, kind='linear', copy='True', bounds_error=False)
    f2 = interp2d(xi, yi, zi2, kind='linear', copy='True', bounds_error=False)

    """ Sans interpolation """
    #"""
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # ax.scatter(ALPHA, THICKNESS)
    ax.plot_trisurf(ALPHA,THICKNESS, CD)
    plt.xlabel('Alpha attack angular in degree'), plt.ylabel('Thickness in percent'),  # plt.zlabel('Drag Coeffictient')
    plt.title('NACA64 Interp')
    plt.show()
    #"""

    """ f1 interp2d """
    """
    # Create cube to match aCube dimensions
    xi = THICKNESS
    yi = ALPHA
    zi = CL

    # Interpolate scattered points
    X, Y= numpy.meshgrid(xi, yi)
    bCube = griddata((xi, yi), zi, (X, Y), method='linear')
    print bCube
    print len(bCube)
    f=interp2d(xi,yi,zi)
    """
    """ Bon résultat with gridddata malgré un plateau à 0"""
    """
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(xi, yi, zi,c='r')
    ax.plot_surface(X, Y, bCube)
    # plt.xlabel('Alpha attack angular in degree'), plt.ylabel('Thickness in percent'),  # plt.zlabel('Drag Coeffictient')
    plt.title('NACA64 Interp')
    plt.show()
    """
    """ Plot interp2d function of thickness """
    """
    fig=plt.figure()
    plt.plot(xi,f1(xi,12))
    plt.show()
    """
    """ Plot interp2d function of angular """
    """
    fig = plt.figure()
    plt.plot(yi, f1(50, yi))
    plt.show()
    """

    """
    grid_x, grid_y=numpy.meshgrid(THICKNESS, ALPHA,sparse=True, copy=False)

    grid_z1=interp2d(grid_x,grid_y,CL,kind='quintic',bounds_error=True,fill_value=0)
    #grid_z1 = interp2d(grid_x, grid_y, CL, kind='linear')

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    #ax.scatter(ALPHA, THICKNESS)
    ax.plot_surface(grid_x, grid_y, grid_z1(THICKNESS,ALPHA))
    #plt.xlabel('Alpha attack angular in degree'), plt.ylabel('Thickness in percent'),  # plt.zlabel('Drag Coeffictient')
    plt.title('NACA64 Interp')
    plt.show()
    """

    """

    xArray=ALPHA
    yArray=THICKNESS
    heightArray=CL
    #point=
    #estimatedHeightList=

    numIndexes = 500
    xi = numpy.linspace(numpy.min(xArray), numpy.max(xArray), numIndexes)
    yi = numpy.linspace(numpy.min(yArray), numpy.max(yArray), numIndexes)

    XI, YI = numpy.meshgrid(ALPHA, THICKNESS)
    points = numpy.vstack((xArray, yArray)).T
    values = numpy.asarray(heightArray)
    points = numpy.asarray(points)
    #values = numpy.asarray(estimatedHeightList)
    DEM = griddata(xArray, yArray, heightArray, xi, yi, interp='linear')
    #DEM = interpolate.griddata(points, values, (XI, YI), method='linear')

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    #ax.scatter(ALPHA, THICKNESS)
    ax.plot_surface(XI, YI, DEM)
    plt.xlabel('Alpha attack angular in degree'), plt.ylabel('Thickness in percent'),  # plt.zlabel('Drag Coeffictient')
    plt.title('NACA64 Interp')
    plt.show()
    """

    return [f1,f2]

def interpolation2d_aerofoil_data_V2(Aero_Mat):
    """
        Function returning for a value of an angle the list (Cl,Cd) interpolate for this angle
        :param profile_index: Index of Profile Number (Exemple for NREL_5MW):
            NACA64: 0
            DU21:   1
            DU25:   2
            DU30:   3
            DU35:   4
            DU40:   5
            Round:  6
        :param alpha: angle of attack in degree
        :return: list Cl,Cd interpolate for this angle
        """
    ALPHA = Aero_Mat[:, 1]
    THICKNESS = Aero_Mat[:, 0]
    CL = Aero_Mat[:, 2]
    CD = Aero_Mat[:, 3]

    x = THICKNESS
    y = ALPHA
    z1 = CL
    z2 = CD

    #f1 = interp2d(xi, yi, zi1, kind='linear', copy='True', bounds_error=False)
    #f2 = interp2d(xi, yi, zi2, kind='linear', copy='True', bounds_error=False)

    f1=rbfi1 = Rbf(x,y,z1,function='linear')
    f2=rbfi2 = Rbf(x,y,z2,function='linear')
    #print rbfi1(50,0)
    #"""
    xi=numpy.linspace(0,100,180)
    yi=numpy.linspace(-180,180,180)

    di1 = rbfi1(xi,yi)
    di2 = rbfi2(xi,yi)
    """
    fig = plt.figure()
    ax = fig.add_subplot(121, projection='3d')
    ax.plot_trisurf(x, y, rbfi1(x, y))
    plt.title('Interpolation of airfoil profile lift coefficient'), plt.xlabel('Thickness in percent'), plt.ylabel(
        'Angular of attack in degree')
    ax = fig.add_subplot(122, projection='3d')
    ax.plot_trisurf(x, y, rbfi2(x, y))
    plt.title('Interpolation of airfoil profile drag coefficient'), plt.xlabel('Thickness in percent'), plt.ylabel(
        'Angular of attack in degree')
    plt.show()
    #"""
    """ Sans interpolation """
    """
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # ax.scatter(ALPHA, THICKNESS)
    ax.plot_trisurf(ALPHA, THICKNESS, CL)
    plt.xlabel('Alpha attack angular in degree'), plt.ylabel('Thickness in percent'),  # plt.zlabel('Drag Coeffictient')
    plt.title('NACA64 Interp')
    plt.show()
    #"""

    return [f1,f2]
######TEST#####

#######################################################################################################################
def Interpolate_ClCd_from_Data(WT):
    """
    Main Function wich extract Aerofoils data for a specific Blade from a file.pos
    and return the interpolated functions derived from this data

    :param WT: Name of the specific Blade
    :return: [f_Cl(thickness, alpha), f_Cd(thickness, alpha)]
    """
    """ Extract Data from a .pos file """
    DATA_Char=get_aerofoils_data(WT)
    Thickness=get_thickness_data(WT)
    """ Convert Char value in floatting Value """
    DATA_Float=CharToFloat(DATA_Char)

    """ Organize DATA to be more easily interpolated """
    DATA=Organize_data_V3(DATA_Float,Thickness)
    Aero_Mat=DATA

    """ Interpolate DATA to return a [[Cl(alpha),Cd()(alpha)],...for each profile]"""

    #L = interpolation2d_aerofoil_data(Aero_Mat)
    L = interpolation2d_aerofoil_data_V2(Aero_Mat)
    Cl = L[0]
    Cd = L[1]

    return [Cl,Cd]

########TEST#####
"""
WT='NREL_5MW'
F=Interpolate_ClCd_from_Data(WT)
print F

Cl=F[0]
Cd=F[1]
#"""
######TO PLOT WITH TEST####
"""
f=Cl
t=15
a=numpy.arange(-180,181,1)
plt.plot(a,f(t,a))
plt.show()

t=numpy.arange(0,10,0.5)
for i in t:
    plt.plot(a,f(i,a), label=str(i))
plt.legend()
plt.show()

plt.plot(a,f(35,a))
plt.show()
t=numpy.arange(40,105,5)
for i in t:
    plt.plot(a,f(i,a), label=str(i))
plt.legend()
plt.show()
#"""


# -*- coding: utf-8 -*-
"""
Calculate options' prices.

Example command for calculating europian option:
python calculate.py -t europian

Example command for calculating asian option:
python calculate.py -t asian

"""
import os
import time
import ConfigParser

from market import (
    MarketData,
    EuropianOption,
    AsianOption
)
from fdms.core import Nodes
from fdms.explicit_fdms import (
    EuropianOptionExplicitFDM,
    AsianOptionExplicitFDM
)
from fdms.implicit_fdms import EuropianOptionImplicitFDM
from argument_parser import OptionsSolverArgumentParser

if __name__ == "__main__":
    config = ConfigParser.RawConfigParser()
    config.read('config.cfg')
    results_path = config.get('other', 'results_path')

    parser = OptionsSolverArgumentParser.get_parser()
    args = parser.parse_args()

    market_data = MarketData(
        interest=config.getfloat(args.type, 'interest_rate'),
        volatility=config.getfloat(args.type, 'volatility')
    )

    if args.type == 'europian':
        method_type = config.get(args.type, 'method_type')
        strike = config.getfloat(args.type, 'strike_price')
        maturity = config.getfloat(args.type, 'maturity')
        time_steps_number = config.getint(args.type, 'time_steps_number')
        asset_price_steps_number = config.getint(
            args.type, 'asset_price_steps_number'
        )
        asset_price_min = config.getfloat(args.type, 'asset_price_min')
        asset_price_max = config.getfloat(args.type, 'asset_price_max')

        if method_type == 'explicit':
            fdm_class = EuropianOptionExplicitFDM
        elif method_type == 'implicit':
            fdm_class = EuropianOptionImplicitFDM
        start_time = time.time()
        option = EuropianOption(
            strike=strike, maturity=maturity
        )
        nodes = Nodes([
            ([0.0, maturity], time_steps_number, 'time'),
            ([asset_price_min, asset_price_max],
             asset_price_steps_number, 'asset_price')
        ])

        fdm = fdm_class(
            option, market_data, nodes
        )

        prices = fdm.calculate_prices()
        end_time = time.time()

        fdm.export_to_file(
            os.path.join(
                results_path,
                "europian %d %d.data.xlsx" %
                (time_steps_number, asset_price_steps_number),
            ),
            points_number=100
        )
        fdm.compare_with_analytical()

        print("Executing time %f" % (end_time - start_time))

    elif args.type == 'asian':
        method_type = config.get(args.type, 'method_type')
        strike = config.getfloat(args.type, 'strike_price')
        maturity = config.getfloat(args.type, 'maturity')
        time_steps_number = config.getint(args.type, 'time_steps_number')
        asset_price_steps_number = config.getint(
            args.type, 'asset_price_steps_number'
        )
        average_price_steps_number = config.getint(
            args.type, 'average_price_steps_number'
        )
        asset_price_min = config.getfloat(args.type, 'asset_price_min')
        asset_price_max = config.getfloat(args.type, 'asset_price_max')
        average_price_min = config.getfloat(args.type, 'average_price_min')
        average_price_max = config.getfloat(args.type, 'average_price_max')

        start_time = time.time()
        option = AsianOption(
            strike=strike, maturity=maturity
        )
        nodes = Nodes([
            ([0.0, maturity], time_steps_number, 'time'),
            ([asset_price_min, asset_price_max],
             asset_price_steps_number, 'asset_price'),
            ([average_price_min, average_price_max],
             average_price_steps_number, 'average_price')
        ])

        fdm = AsianOptionExplicitFDM(
            option, market_data, nodes
        )

        prices = fdm.calculate_prices()
        end_time = time.time()
        fdm.plot_option_prices(asset_price_sparse=35, average_price_sparse=20)
        fdm.export_to_file(
            os.path.join(
                results_path,
                "asian_data %d %d %d.xlsx" %
                (time_steps_number, asset_price_steps_number,
                 average_price_steps_number)
            )
        )
        print("Executing time %f" % (end_time - start_time))
    else:
        raise ValueError(
            "Only europian and asian options are supported at this moment"
        )


def loadDataSet():
    return [[1, 2, 3], [1, 4, 5], [1, 3, 6], [4, 5, 6], [2, 3, 6], [1, 3, 4, 5], [3, 4, 5], [2, 3], [1, 3, 4, 5],[2, 6]]

def createC1(dataSet):
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])
    C1.sort()
    return list(map(frozenset, C1))

def scanD(D, Ck, minSupport):
    ssCnt = {}
    for tid in D:
        for can in Ck:
            if can.issubset(tid):
                if can not in ssCnt:
                    ssCnt[can] = 1
                else:
                    ssCnt[can] += 1
    numItems = float(len(D))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key] / numItems
        if support >= minSupport:
            retList.insert(0, key)
        supportData[key] = support
    return retList, supportData

def aprioriGen(Lk, k):
    retList = []
    lenLk = len(Lk)
    for i in range(lenLk):
        for j in range(i + 1, lenLk):
            L1 = list(Lk[i])[:k - 2]
            L2 = list(Lk[j])[:k - 2]
            L1.sort()
            L2.sort()
            if L1 == L2:
                retList.append(Lk[i] | Lk[j])  # 求并集
    return retList

def apriori(dataSet, minSupport=0.3):
    D = list(map(set, dataSet))
    C1 = createC1(dataSet)
    L1, supportData = scanD(D, C1, minSupport)
    L = [L1]
    k = 2
    while (len(L[k - 2]) > 0):
        Ck = aprioriGen(L[k - 2], k)
        Lk, supK = scanD(D, Ck, minSupport)
        supportData.update(supK)
        L.append(Lk)
        k += 1
    return L, supportData

def generateRules(L, supportData, minConf=0.7):
    bigRuleList = []
    for freqSet in L[len(L)-2]:
        H1 = [frozenset([item]) for item in freqSet]
        calcConf(freqSet, H1, supportData, bigRuleList, minConf)
    return bigRuleList

def calcConf(freqSet, H, supportData, brl, minConf=0.7):
    prunedH = []
    for conseq in H:
        conf = supportData[freqSet] / supportData[freqSet - conseq]
        if conf >= minConf:
            # print(freqSet - conseq, '-->', conseq, 'conf:', conf)
            brl.append((freqSet - conseq, conseq, conf))
            prunedH.append(conseq)
    return prunedH

dataSet = loadDataSet()
L, suppData = apriori(dataSet, minSupport=0.3)
rules = generateRules(L, suppData, minConf=0.7)
# print(suppData)
for i in range(len(L)):
    print("频繁",i+1,"项集:", L[i])
print("关联规则:", rules)


from easydict import EasyDict

__C = EasyDict()

# ===========================================

__C.train_csv_path = '../inputs/train.csv'
__C.test_csv_path = '../inputs/test.csv'
__C.pred_path = '../results/'
__C.single_model_pred_path = __C.pred_path + 'single_model/'
__C.prejudge_pred_path = __C.pred_path + 'prejudge/'
__C.stack_pred_path = __C.pred_path + 'stacking/'
__C.auto_train_pred_path = __C.pred_path + 'auto_train/'
__C.log_path = '../logs/'
__C.csv_log_path = __C.log_path + 'csv_logs/'
__C.grid_search_out_path = '../grid_search_outputs/'
__C.boost_round_out_path = '../boost_round_outputs/'
__C.loss_log_path = __C.log_path + 'loss_logs/'
__C.prejudge_loss_log_path = __C.loss_log_path + 'prejudge/'
__C.dnn_log_path = __C.log_path + 'dnn_logs/'
__C.grid_search_log_path = __C.log_path + 'grid_search_logs/'
__C.data_path = '../data/'
__C.preprocessed_path = __C.data_path + 'preprocessed_data/'
__C.gan_prob_path = __C.data_path + 'gan_outputs/'
__C.gan_preprocessed_data_path = __C.data_path + 'gan_preprocessed_data/'
__C.preprocessed_data_path = __C.preprocessed_path
__C.prejudged_data_path = __C.data_path + 'prejudged_data/'
__C.stack_output_path = __C.data_path + 'stacking_outputs/'
__C.model_checkpoint_path = '../checkpoints/'
__C.dnn_checkpoint_path = __C.model_checkpoint_path + 'dnn_checkpoints/'
__C.tsne_outputs_path = __C.data_path + 'tsne_outputs/'

# ===========================================

# get config by: from config import cfg
cfg = __C


from django.shortcuts import render
# from django.http import HttpResponse
from datetime import datetime
from django.shortcuts import render
# Create your views here.

posts = [
    {
        'name':'Como la flor',
        'user': 'Josue Torres',
        'timestamp': datetime.now().strftime('%b %dth, %Y - %H:%M hrs'),
        'picture': 'https://image.freepik.com/foto-gratis/imagen-primer-plano-flores-imagen-macro-utiliza-como-imagen-fondo-foto-primer-plano-macro_34433-346.jpg',
    },
    {
        'name':'Luna',
        'user': 'Ruben Torres',
        'timestamp': datetime.now().strftime('%b %dth, %Y - %H:%M hrs'),
        'picture': 'https://dam.ngenespanol.com/wp-content/uploads/2019/03/luna-colores-nuevo-770x395.png',
    },
    {
        'name':'Luna',
        'user': 'Silvia Valdez',
        'timestamp': datetime.now().strftime('%b %dth, %Y - %H:%M hrs'),
        'picture': 'https://d500.epimg.net/cincodias/imagenes/2018/11/13/lifestyle/1542113135_776401_1542116070_noticia_normal.jpg',
    },
]

    # .format(**post))
    # import pdb; pdb.set_trace()

def list_posts(request):
    # """Busca automaticamente dentro de la carpeta tempplates
    # y recive como argumento contexto que es un diccionario """
    return render(request, 'feed.html', { 'posts': posts })

    # content = []
    # for post in posts:
    #     content.append("""
    #
{name}

    #
{user} - {timestamp}

    #

    #     """.format(name=post['name'], user=post['user'], picture=post['picture'], timestamp=post['timestamp']))
    # return HttpResponse('
'.join(content))


import time
from turtle import Turtle, Screen
from food import Food
from snake import Snake
from scoreboard import Scoreboard

screen = Screen()
screen.setup(width=600, height=600)
screen.title('Snake Game')
screen.bgcolor('black')
screen.tracer(0)

snake = Snake()
food = Food()
scoreboard = Scoreboard()
# high_score = HighScore(scoreboard.score)

screen.listen()
screen.onkey(key='Up', fun=snake.up)
screen.onkey(key='Down', fun=snake.down)
screen.onkey(key='Left', fun=snake.left)
screen.onkey(key='Right', fun=snake.right)

NUMBER = 300

def has_hit_the_wall():
    if snake.head.xcor() >= NUMBER or snake.head.xcor() <= -NUMBER or snake.head.ycor() >= NUMBER or snake.head.ycor() <= -NUMBER:
        return True

game_is_on = True

while game_is_on:
    screen.update()
    time.sleep(0.1)
    snake.move()
    if snake.head.distance(food) < 15:
        food.refresh()
        snake.extend()
        scoreboard.add_score_point()

    if has_hit_the_wall():
        scoreboard.reset_score()
        snake.reset_snake()
    for segment in snake.segments[1:]:
        if segment == snake.head:
            pass
        elif snake.head.distance(segment) < 10:
            scoreboard.reset_score()
            snake.reset_snake()
screen.exitonclick()


from abc import ABC, abstractmethod
from dataclasses import dataclass

@dataclass
class Rock(ABC):
    """
    Representation of a rock
    Co-ordinates of rock pieces use (0,0) as bottom-left most piece
    """

    position: tuple

    @property
    def full_position(self):
        return set((x + self.x_position, y + self.y_position) for x, y in self.shape)

    @property
    def x_position(self):
        return self.position[0]

    @property
    def y_position(self):
        return self.position[1]

    @property
    @abstractmethod
    def shape(self):
        pass

    @property
    def right_edge(self) -> int:
        """Return the furthest right point on the shape"""
        return max(part[0] for part in self.full_position)

    @property
    def left_edge(self) -> int:
        """Return the furthest left point on the shape"""
        return min(part[0] for part in self.full_position)

    @property
    def bottoms(self) -> set:
        """Return set of lowest locations"""
        pos_dict = {}
        for part in self.full_position:
            x, y = part
            if pos_dict.get(x) is None:
                pos_dict[x] = []
            pos_dict[x].append(y)

        return set((key, max(value)) for key, value in pos_dict.items())

    def move_down(self):
        """Moves rock down one position"""
        self.position = (self.x_position, self.y_position - 1)

    def move_left(self):
        """Moves rock left one position if possible"""
        self.position = (self.x_position - 1, self.y_position)

    def move_right(self):
        """Moves rock left one position if possible"""
        self.position = (self.x_position + 1, self.y_position)

@dataclass
class Hero(Rock):
    """
    ####
    """

    name = "Hero"
    shape = {(0, 0), (1, 0), (2, 0), (3, 0)}
    width = 4

@dataclass
class CrossMan(Rock):
    """
    .#.
    ###
    .#.
    """

    name = "CrossMan"
    shape = {(1, 0), (0, 1), (1, 1), (2, 1), (1, 2)}
    width = 3

class BigEll(Rock):
    """
    ..#
    ..#
    ###
    """

    name = "BigEll"
    shape = {(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)}
    width = 3

class TallPaul(Rock):
    """
    #
    #
    #
    #
    """

    name = "TallPaul"
    shape = {(0, 0), (0, 1), (0, 2), (0, 3)}
    width = 1

class Smashboy(Rock):
    """
    ##
    ##
    """

    name = "SmashBoy"
    shape = {(0, 0), (0, 1), (1, 0), (1, 1)}
    width = 2

class RockFactory:

    rocks = [Hero, CrossMan, BigEll, TallPaul, Smashboy]
    pointer = 0

    @classmethod
    def get_next_rock(cls, height: int):
        """Returns next rock in sequence at specfied height"""
        next_rock = cls.rocks[cls.pointer]
        cls.pointer = (cls.pointer + 1) % len(cls.rocks)
        return next_rock((2, height))


"""This module defines the models and schemas used by the 'note' entities of the API."""
import os

from marshmallow import validates
from marshmallow.validate import Length
from umongo import Document, fields, post_load, ValidationError
from umongo.frameworks import PyMongoInstance, MongoMockInstance

from notes.user.model import auth

note_umongo_instance = PyMongoInstance() if not os.getenv("MOCK_MONGO") else MongoMockInstance()

@note_umongo_instance.register
class Note(Document):
    """A MongoDB model for the 'note' document."""
    username = fields.StrField(required=True)
    title = fields.StrField(
        required=True,
        validate=Length(min=1, max=20),
        metadata={
            "title": "Note title",
            "description": "Title of the note"
        }
    )
    text = fields.StrField(
        required=True,
        validate=Length(min=1),
        metadata={
            "title": "Note text",
            "description": "Text of the note"
        }
    )
    added_timestamp = fields.DateTimeField(
        metadata={
            "title": "Time of creation",
            "description": "Timestamp added to the note at the time of creation"
        }
    )
    modified_timestamp = fields.DateTimeField(
        metadata={
            "title": "Time of last modification",
            "description": "Timestamp of the last modification"
        }
    )

    class Meta:
        collection_name = "notes"
        indexes = ("title", "text")

NoteSchema = Note.schema.as_marshmallow_schema()

class InNoteSchema(NoteSchema):
    """A schema that defines input fields for a 'note' document."""

    def __init__(self, *args, update: bool = False, **kwargs):
        """Add an 'update' field to object instance for usage in validation.

        :param update: whether the schema is used in 'update' operation.
        """
        NoteSchema.__init__(self, *args, **kwargs)
        self.update = update

    @post_load
    def add_username(self, data: dict, **kwargs) -> dict:
        """Update the data with current user's username after loading.

        :param data: data loaded with this schema.
        :return: updated data.
        """
        data["username"] = auth.current_user["username"]
        return data

    @validates("title")
    def unique_title(self, value: str):
        """Validate that title is unique for user.

        :param value: value of the field.
        :raise: marshmallow.ValidationError if a note with given title already exists for user.
        """
        if Note.find_one({"title": value, "username": auth.current_user["username"]}) and not self.update:
            raise ValidationError("Title must be unique")

    class Meta:
        fields = ("title", "text")

class QueryNoteSchema(NoteSchema):
    title = fields.StrField(
        validate=Length(max=20),
        metadata={
            "title": "Note title",
            "description": "Title of the note"
        }
    )
    text = fields.StrField(
        metadata={
            "title": "Note text",
            "description": "Text of the note"
        }
    )

    class Meta:
        fields = ("title", "text")

class OutNoteSchema(NoteSchema):
    """A schema that defines output fields for a 'note' document."""

    class Meta:
        fields = ("title", "added_timestamp", "modified_timestamp", "text")


# Question given to me by Nick: apparently it's the actual Digit phone screen q
# Started 1315
# Solved 1330
# [1, 1] infinite loops

from typing import List

def traverse(idx: int, a: List[int], visited: List[int]) -> bool:
    '''Recursive function that returns True iff a zero can be reached
    from the current node index'''
    # When we reach a node, first check if its visited
    # If it is visited, return False, we're done

    # When we reach a node, we check if its 0
    # If it is, return True. We're done

    # If it isn't 0, then we can move forwards or backwards
    # do recursive call on both the forwads and backwards node

    # First check if idx is out of bounds
    if idx < 0 or idx >= len(a):
        return False
    if visited[idx]:
        return False
    if a[idx] == 0:
        return True
    steps = a[idx]  # this won't throw an error because we checked bounds
    visited[idx] = True
    return any([traverse(idx + steps, a, visited),
                traverse(idx - steps, a, visited)]
               )

def findZero(a: List[int]) -> bool:
    visited = [False for _ in a]
    return traverse(0, a, visited)

# [3, 7, 0, 2, 8, 3, 7, 6] # True

def s(a: List[int]):
    r = (findZero(a))
    print(r)
    return r

s([])  # False
s([0])  # True
s([1, 1])  # False
s([1, 0])  # True
s([2, 0])  # False
assert(s([3, 7, 0, 2, 8, 3, 7, 6]) is True)

'''
Trace output
[] => idx = 0 = len([]) => False
[1,0] => idx = 0, a[idx] = 1, visited[1] = True, any(traverse(-1,...), traverse(1...))
    => -1 will return False, and then the a[1] == 0 return True
[1,1]  => idx = 0, a[idx] = 1, visited[1] = True, any(traverse(-1,...), traverse(1...))
        => traverse(0), traverse(2)
        traverse(0) => False because of visited[idx]
        traverse(2) => False because OOB
        => False
[3, 7, 0, 2, 8, 3, 7, 6] # True
    => idx = 0 , a[idx] = 1, any(traverse(-3), traverse(3))
        => traverse(3) => idx = 3, a[idx] = 2, traverse(1), traverse(5)
            => traverse (1) ==> 7 , traverse(-6), traverse(8) => False
            => traverse(5) ==> 3, traverse(2), traverse(8) => False
                => traverse(2) => 0 . So we return True
'''


from flask import Flask, request, jsonify
import os
import random
import time
import utils
import torch
import pdb
import numpy as np
from torch.utils.data import DataLoader
from utils import calculate_eer, step_decay, extract_all_feat
from tqdm import tqdm as tqdm
from hparam import hparam as hp
from data_load import VoxCeleb, VoxCeleb_utter
#from speech_embedder_net import SpeechEmbedder, GE2ELoss, get_centroids, get_cossim
#from speech_embedder_net import Resnet34_VLAD, SpeechEmbedder, GE2ELoss, SILoss, get_centroids, \
#get_cossim, HybridLoss
from speech_embedder2 import SpeakerRecognition, SILoss
import wave
torch.manual_seed(hp.seed)
np.random.seed(hp.seed)
random.seed(hp.seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
os.environ["CUDA_VISIBLE_DEVICES"] =str(hp.device) # for multiple gpus
from get_embedding import get_embedding

logger = utils.init_logger('voice detection model')

app = Flask(__name__)

@app.route('/test', methods = ['POST'])
def test():
    if request.method == 'POST':
        req_json = request.json

        name = req_json['name']
        #answer = 'length of the req json is ' + str(len(req_json))
        return jsonify({'length of the req json': str(len(req_json)) })

@app.route('/health', methods = ['POST'])
def check():
    if request.method == 'POST':
        return jsonify({'response':'OK!'})

def get_customer_voice_10_seconds(file):
    voice = AudioSegment.from_wav(file)
    new_voice = voice[0:10000]
    file = str(file) + '_10seconds.wav'
    new_voice.export(file, format='wav')

@app.route('/get_embedding', methods = ['POST'])
def show_embedding():
    if request.method == 'POST':

        file1 = request.files["file1"]
        if file1 == None:
            return jsonify({'response': 'BAD, no file given!'})
        else:

            embedding = get_embedding(file1)
            return jsonify({'response': str(embedding)})

@app.route('/process_all', methods = ['POST'])
def process_all():
    if request.method == 'POST':
        file_wav = request.files['file_wav']
        if file_wav == None:
            return jsonify({'response': 'BAD, no wav conversation file given!'})
        else:

            embedding = get_embedding(file_wav)
            return jsonify({'response': str(embedding)})

@app.route('/compare_voices', methods = ['POST'])
def compare_voices():
    file1 = request.files["file1"]
    file2 = request.files["file2"]

    embedding1 = get_embedding(file1)
    embedding2 = get_embedding(file2)

    embedding1 = embedding1 / torch.norm(embedding1, dim=1).unsqueeze(1)
    embedding2 = embedding2 / torch.norm(embedding2, dim=1).unsqueeze(1)
    score = torch.dot(embedding1.squeeze(0), embedding2.squeeze(0)).item()
    print(score)
    answer = ''
    if score > 0.9:
        answer = 'pass '
    else:
        answer = 'no pass '
    score = float(score*100)
    score = '%.2f' % score
    score = str(score)
    answer += score
    return jsonify({'response': answer })

import logging
import pandas as pd
import numpy as np

FORMAT = '[%(asctime)s] [%(process)d] [%(levelname)7s] [%(filename)s:%(lineno)s]: %(message)s'
DATE_FORMAT = '%Y-%m-%d %H:%M:%S %z'

def init_logger(name):
    # Formatters
    formatter = logging.Formatter(fmt=FORMAT, datefmt=DATE_FORMAT)

    # Handlers
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(formatter)
    console_handler.setLevel(logging.DEBUG)

       # Loggers
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)  # root level
    logger.addHandler(console_handler)
    return logger

class ApiError(Exception):
    result = None
    errcode = None
    errtext = None

    def __init__(self, errcode, errtext):
        Exception.__init__(self)
        self.result = 'err'
        self.errcode = errcode
        self.errtext = errtext

    def get_error(self):
        return {'result': self.result, 'errcode': self.errcode, 'errtext': self.errtext}

    def __str__(self):
        return str(self.get_error())

if __name__ == '__main__':
    app.run(debug=True, port=9090)


import os
import cv2
import numpy as np
from PIL import Image

#directory='YOLO/yolo_frames'
#file_name=0

net = cv2.dnn.readNet("YOLO/yolov3.weights", "YOLO/yolov3.cfg")
classes = []
with open("YOLO/coco.names", "r") as f:
    classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

cap=cv2.VideoCapture('walking.avi')

while True:
    for i in range(5):
        _,frame= cap.read()
    frame = cv2.resize(frame, (500,500))
    height, width, channels = frame.shape

    blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    net.setInput(blob)
    outs = net.forward(output_layers)

    class_ids = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.5:
                # Object detected
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                w = int(detection[2] * width)
                h = int(detection[3] * height)

                # Rectangle coordinates
                x = int(center_x - w / 2)
                y = int(center_y - h / 2)

                boxes.append([x, y, w, h])
                confidences.append(float(confidence))
                class_ids.append(class_id)

    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

    font = cv2.FONT_HERSHEY_PLAIN

    for i in range(len(boxes)):
        if i in indexes:
            x, y, w, h = boxes[i]
            label = str(classes[class_ids[i]])

            if label=='person':
                cv2.rectangle(frame, (x, y), (x + w, y + h), (255,0,0), 2)
                cv2.putText(frame, label, (x, y), font, 1, (0,0,255), 2)

    """  The following commented code is to save the frames of the object detected video """

    # im = Image.fromarray(frame, 'RGB')
    # im.save(os.path.join(directory, str(file_name)+".jpg"), "JPEG")
    # file_name = file_name + 1

    cv2.imshow("Capturing", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()


# exo 6.15
# Trouvez la chaîne de caractères la plus longue dans une liste.
# Affichez son index, sa valeur et sa longueur.

my_list = ['Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit']

# réponse 6.15

i=0
str_max=""
# print(my_list[i]);

for item1  in my_list :
    # print (item1)
    for item2 in my_list :
        # print (len(item1));
        if (len(item1) > len(item2)) :
            str_max=item1
        else:
            if (len(item1) == len(item2)):
                str_max=item1
            else :
                str_max=item2

#    i += 1 ;
#     print(i);
#     if item1 > item2:
#         str_max=item1 ;
#     else :
#         str_max=item2 ;

print (str_max);


#!/usr/bin/python3

import sys

from typing import List

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        base = 10

        if len(digits) == 0:
            return [0]

        if len(digits) == 1 and digits[0] == base - 1:
            return [1, 0]

        if digits[-1] == base - 1:
            return self.plusOne(digits[:len(digits) - 1]) + [0]
        else:
            digits[-1] += 1
            return digits

if __name__ == "__main__":
    print("Args: %s" % (sys.argv[1:]))

    digits = [int(i) for i in sys.argv[1:]]

    solution = Solution()
    retList = solution.plusOne(digits)

    print("Result: %s" % (retList))