import os
import h5py
import vigra
import numpy

class TPDError(RuntimeError):
    pass

class TrainPredictData(object):
    """
    The TrainPredictData class can be used to store and load .tpd files (data
    which is associated with a train / predict workflow).
    """

    # The paths that are used inside the .tpd file.
    _tpd_train_raw_path = "train_raw_path"
    _tpd_train_raw_key = "train_raw_key"
    _tpd_train_gt_path = "train_gt_path"
    _tpd_train_gt_key = "train_gt_key"
    _tpd_train_feat = "train_feat"
    _tpd_train_shape = "train_shape"
    _tpd_train_pred_path = "train_pred_path"
    _tpd_train_pred_key = "train_pred_key"
    _tpd_test_raw_path = "test_raw_path"
    _tpd_test_raw_key = "test_raw_key"
    _tpd_test_gt_path = "test_gt_path"
    _tpd_test_gt_key = "test_gt_key"
    _tpd_test_feat = "test_feat"
    _tpd_test_shape = "test_shape"
    _tpd_test_pred_path = "test_pred_path"
    _tpd_test_pred_key = "test_pred_key"

    @staticmethod
    def _check_file_exists(file_name):
        """Raise an exception if the given file does not exist.

        :param file_name: file name relative to the working directory
        """
        if not os.path.isfile(file_name):
            raise TPDError("_check_file_exists(): The given file does not exist.")

    @staticmethod
    def _get_count(shape):
        """Return the number of instances, given a shape.

        :param shape: shape
        :return: number of instances
        """
        from functools import reduce
        from operator import mul
        return reduce(mul, shape, 1)

    def __init__(self, file_name, use_abs_paths=False):
        """
        Create a TrainPredictData instance by loading the given file.
        If the given file does not exist, it will be created.

        :param file_name: file name
        :param use_abs_paths: when adding new data sets, the absolute path will be used instead of the relative path
        """
        self.file_name = file_name
        self.use_abs_paths = use_abs_paths
        dirname = os.path.dirname(self.file_name)
        if len(dirname) == 0:
            dirname = "."
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        self.base_path = os.path.relpath(dirname)

        # Check if the file can be opened with h5py.
        # If it does not exist, it will be created by h5py.
        f = h5py.File(file_name, "a")
        f.close()

    def _to_tpd_path(self, file_name):
        """
        Given a file name relative to the working directory, return the
        file path relative to the .tpd file considering the abs path setting.

        :param file_name: file name relative to working directory
        :return: file name relative to .tpd file considering abs path setting
        """
        if self.use_abs_paths:
            path = os.path.abspath(file_name)
        else:
            path = os.path.relpath(file_name, start=self.base_path)
        return path

    def _to_rel_path(self, file_name):
        """
        Given a file name relative to the .tpd file, return the
        file path relative to the current working directory.

        :param file_name: file name relative to the .tpd file or abs path
        :return: file name relative to the working directory
        """
        if os.path.isabs(file_name):
            path = os.path.relpath(file_name)
        else:
            path = os.path.join(self.base_path, file_name)
        return path

    def _set_data(self, file_name, h5_key, tpd_path, tpd_key, tpd_shape):
        """Set file name and h5 key of the data.

        :param file_name: file name
        :param h5_key: h5 key
        :param tpd_path: tpd key of the file
        :param tpd_key: tpd key of the h5 key
        :param tpd_shape: tpd key with the shape of the data
        """
        self._check_file_exists(file_name)

        # Read the shape of the new data set.
        with h5py.File(file_name, "r") as f:
            if h5_key not in f.keys():
                raise TPDError("_set_data(): The given h5 key does not exist in the given file.")
            new_shape = f[h5_key].shape
        new_count = self._get_count(new_shape)

        with h5py.File(self.file_name, "a") as f:
            # Check if the data shapes match.
            if tpd_shape in f.keys():
                shape = tuple(f[tpd_shape].value)
                count = self._get_count(shape)
                if new_count != count:
                    raise TPDError("_set_data(): The numbers of instances do not match.")
            else:
                f[tpd_shape] = new_shape

            if tpd_path in f.keys():
                del f[tpd_path]
            f[tpd_path] = self._to_tpd_path(file_name)
            if tpd_key in f.keys():
                del f[tpd_key]
            f[tpd_key] = h5_key

    def _get_data(self, tpd_path, tpd_key):
        """Return file name and h5 key of the data.

        :param tpd_path: tpd key of the file
        :param tpd_key: tpd key of the h5 key
        :return: file name, h5 key
        """
        with h5py.File(self.file_name, "r") as f:
            if tpd_path not in f.keys() or tpd_key not in f.keys():
                raise TPDError("_get_data(): The .tpd file does not contain the desired data.")
            file_name = f[tpd_path].value
            h5_key = f[tpd_key].value
        file_name = self._to_rel_path(file_name)
        return file_name, h5_key

    def set_train_raw(self, file_name, h5_key):
        """Set file name and h5 key of the training raw data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_train_raw_path, self._tpd_train_raw_key,
                       self._tpd_train_shape)

    def get_train_raw(self):
        """Return file name and h5 key of the training raw data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_train_raw_path, self._tpd_train_raw_key)

    def get_train_raw_data(self):
        """Return the training raw data.

        :return: training raw data
        """
        file_name, h5_key = self.get_train_raw()
        return vigra.readHDF5(file_name, h5_key)

    def set_train_gt(self, file_name, h5_key):
        """Set file name and h5 key of the training gt data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_train_gt_path, self._tpd_train_gt_key,
                       self._tpd_train_shape)

    def get_train_gt(self):
        """Return file name and h5 key of the training raw data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_train_gt_path, self._tpd_train_gt_key)

    def get_train_gt_data(self):
        """Return the training gt data.

        :return: training gt data
        """
        file_name, h5_key = self.get_train_gt()
        return vigra.readHDF5(file_name, h5_key)

    def set_test_raw(self, file_name, h5_key):
        """Set file name and h5 key of the test raw data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_test_raw_path, self._tpd_test_raw_key,
                       self._tpd_test_shape)

    def get_test_raw(self):
        """Return file name and h5 key of the test raw data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_test_raw_path, self._tpd_test_raw_key)

    def get_test_raw_data(self):
        """Return the test raw data.

        :return: test raw data
        """
        file_name, h5_key = self.get_test_raw()
        return vigra.readHDF5(file_name, h5_key)

    def set_test_gt(self, file_name, h5_key):
        """Set file name and h5 key of the test gt data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_test_gt_path, self._tpd_test_gt_key,
                       self._tpd_test_shape)

    def get_test_gt(self):
        """Return file name and h5 key of the test gt data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_test_gt_path, self._tpd_test_gt_key)

    def get_test_gt_data(self):
        """Return the test gt data.

        :return: test gt data
        """
        file_name, h5_key = self.get_test_gt()
        return vigra.readHDF5(file_name, h5_key)

    def _add_feature(self, file_name, h5_key, tpd_key, tpd_shape):
        """
        Add the given feature to the training or test data, depending on the tpd key.
        The feature will only be added, if it is not already in the feature list.

        :param file_name: file name
        :param h5_key: h5 key
        :param tpd_key: key in the .tpd file
        :param tpd_shape: key in the .tpd file with the shape of the data
        """
        self._check_file_exists(file_name)
        to_add = [self._to_tpd_path(file_name), h5_key]

        # Read the instance count from the given file.
        with h5py.File(file_name, "r") as f:
            if h5_key not in f.keys():
                raise TPDError("_add_feature(): The given h5 key does not exist in the given file.")
            new_shape = f[h5_key].shape
        new_shape_count = self._get_count(new_shape)
        new_count = new_shape[0]

        # Append the new feature to the feature list.
        with h5py.File(self.file_name, "a") as f:
            # Get the current feature list.
            if tpd_key in f.keys():
                feature_list = f[tpd_key].value.tolist()
            else:
                feature_list = []

            # Get the shape of the old data.
            if tpd_shape in f.keys():
                shape = tuple(f[tpd_shape].value)
                count = self._get_count(shape)
                if new_count != count and new_shape_count != count:
                    raise TPDError("_add_feature(): The numbers of instances do not match.")

            # Append the feature to the list.
            if to_add not in feature_list:
                feature_list.append(to_add)

            if tpd_key in f.keys():
                del f[tpd_key]
            f[tpd_key] = numpy.array(feature_list)

    def add_train_feature(self, file_name, h5_key):
        """Add the given training feature, but only if it is not already in the feature list.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._add_feature(file_name, h5_key, self._tpd_train_feat, self._tpd_train_shape)

    def add_test_feature(self, file_name, h5_key):
        """Add the given test feature, but only if it is not already in the feature list.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._add_feature(file_name, h5_key, self._tpd_test_feat, self._tpd_test_shape)

    def _get_feature_file(self, tpd_key, i):
        """Get file name and h5 key of the feature with index i.

        :param tpd_key: tpd key of the data
        :param i: feature index
        :return: file name, h5 key
        """
        with h5py.File(self.file_name, "r") as f:
            if tpd_key not in f.keys():
                raise TPDError("_get_feature_file(): There are no features in the .tpd file.")
            feature_list = f[tpd_key].value.tolist()

        if i < 0 or i >= len(feature_list):
            raise TPDError("_get_feature_file(): Index out of range.")
        return self._to_rel_path(feature_list[i][0]), feature_list[i][1]

    def get_train_feature_file(self, i):
        """Get file name and h5 key of the training feature with index i.

        :param i: feature index
        :return: file name, h5 key
        """
        return self._get_feature_file(self._tpd_train_feat, i)

    def get_test_feature_file(self, i):
        """Get file name and h5 key of the test feature with index i.

        :param i: feature index
        :return: file name, h5 key
        """
        return self._get_feature_file(self._tpd_test_feat, i)

    def _get_feature_data(self, tpd_key, tpd_shape):
        """Get the features of the desired data set.

        :param tpd_key: tpd key of the data
        :param tpd_shape: tpd key of the shape of the raw data
        :return: features of the desired data set
        """
        with h5py.File(self.file_name, "r") as f:
            if tpd_key not in f.keys():
                raise TPDError("_get_feature_data(): There are no features in the .tpd file.")
            feature_list = f[tpd_key].value.tolist()
            if tpd_shape in f.keys():
                shape = tuple(f[tpd_shape].value)
                count = self._get_count(shape)
            else:
                shape = None

        # Check that the number of instances in all feature files is correct and get the number of features.
        num_all_feats = []
        for file_path, h5_key in feature_list:
            # Read the shape of the feature data.
            file_path = self._to_rel_path(file_path)
            with h5py.File(file_path, "r") as f:
                if h5_key not in f.keys():
                    raise TPDError("_get_feature_data(): The h5 key does not exist in the given file.")
                new_shape = f[h5_key].shape
            new_count = self._get_count(new_shape)
            if shape is None:
                shape = new_shape
                count = self._get_count(shape)

            # Get the number of features that are inside the current data set.
            if new_count == count:
                num_all_feats.append(1)
            elif new_shape[0] == count:
                num_all_feats.append(self._get_count(new_shape[1:]))
            else:
                raise TPDError("_get_feature_data(): The numbers of instances do not match.")

        # Write all features into a single numpy array.
        feats = numpy.zeros((count, sum(num_all_feats)))
        current_feat = 0
        for i in xrange(len(num_all_feats)):
            file_path, h5_key = feature_list[i]
            file_path = self._to_rel_path(file_path)
            num_feats = num_all_feats[i]

            # Read the feature data.
            with h5py.File(file_path, "r") as f:
                feat = f[h5_key].value
            feat = feat.reshape((count, num_feats))

            # Write all features into the feature array.
            for k in xrange(num_feats):
                feats[:, current_feat] = feat[:, k]
                current_feat += 1

        return feats

    def get_train_features(self):
        """Return a (n, d) numpy array with the training features (n instances, d features).

        :return: training features
        """
        return self._get_feature_data(self._tpd_train_feat, self._tpd_train_shape)

    def get_test_features(self):
        """Return a (n, d) numpy array with the test features (n instances, d features).

        :return: test features
        """
        return self._get_feature_data(self._tpd_test_feat, self._tpd_test_shape)

    def _clear_features(self, tpd_key):
        """Clear the list with features.
        """
        with h5py.File(self.file_name) as f:
            if tpd_key in f.keys():
                del f[tpd_key]

    def clear_train_features(self):
        """Clear the list with training features.
        """
        self._clear_features(self._tpd_train_feat)

    def clear_test_features(self):
        """Clear the list with test features.
        """
        self._clear_features(self._tpd_test_feat)

    def set_train_pred(self, file_name, h5_key):
        """Set file name and h5 key of the training prediction data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_train_pred_path, self._tpd_train_pred_key,
                       self._tpd_train_shape)

    def get_train_pred(self):
        """Return file name and h5 key of the training prediction data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_train_pred_path, self._tpd_train_pred_key)

    def get_train_pred_data(self):
        """Return the training prediction data.

        :return: training prediction data
        """
        file_name, h5_key = self.get_train_pred()
        return vigra.readHDF5(file_name, h5_key)

    def set_test_pred(self, file_name, h5_key):
        """Set file name and h5 key of the test prediction data.

        :param file_name: file name
        :param h5_key: h5 key
        """
        self._set_data(file_name, h5_key,
                       self._tpd_test_pred_path, self._tpd_test_pred_key,
                       self._tpd_test_shape)

    def get_test_pred(self):
        """Return file name and h5 key of the test prediction data.

        :return: file name, h5 key
        """
        return self._get_data(self._tpd_test_pred_path, self._tpd_test_pred_key)

    def get_test_pred_data(self):
        """Return the test prediction data.

        :return: test prediction data
        """
        file_name, h5_key = self.get_test_pred()
        return vigra.readHDF5(file_name, h5_key)

    def show(self):
        """Show raw and ground truth data of training and test set.
        """
        from PyQt4.QtGui import QApplication
        from segmentation.labeling.faceLabeling import FaceLabeler
        app = QApplication([])
        v = FaceLabeler(numpy.array([0]), [0, 0, 0, 0])

        try:
            raw_train = self.get_train_raw_data()
            v.addGrayscaleLayer(raw_train, "raw train")
        except TPDError:
            pass

        try:
            gt_train = self.get_train_gt_data()
            v.addRandomColorsLayer(gt_train, "gt train")
        except TPDError:
            pass

        try:
            raw_test = self.get_test_raw_data()
            v.addGrayscaleLayer(raw_test, "raw test")
        except TPDError:
            pass

        try:
            gt_test = self.get_test_gt_data()
            v.addRandomColorsLayer(gt_test, "gt test")
        except TPDError:
            pass

        v.show()
        app.exec_()


import ssl
import os
import pandas as pd
import glob
import csv
import re
import numpy as np
import datetime as dt
from pandas.core.indexes.base import Index

codelist=['9983','7751','5201','2871','9613','6752','4507','2809','8411','5332','3407','2296']
path="stock_data\\"
df1 = pd.read_csv(path + "stockopencode.csv",encoding="cp932")

df1['date'] = pd.to_datetime(df1['date'])
df5 = df1[df1['date']>dt.datetime(2018,7,1)]
for code in codelist:
    print(code)
    if not code in df1.columns:
        continue
    colist = []
    df2 = df5[code]
    df2 = df2.reset_index(drop = True)
    length = len(df2)
    length = length - 1
    for s in df1.columns[3::]:
        df3 = df1.loc[0:length,s]

        df4 = pd.concat([df2,df3],axis=1)
        df4.columns = ['1','2']
        df4 = df4[(df4["1"] != 0 ) & (df4['2'] != 0) ]
        corr = df4.corr()
        colist.append(corr.loc['1','2'])
    colist_sort=sorted(colist,reverse=True)
    print(colist_sort[0:5])
    indexlist = []
    for i in colist_sort[0:5]:
        indexnum = colist.index(i)
        indexlist.append(indexnum+3)
    print(df1.columns[indexlist])


import re
from lark import Lark, InlineTransformer
from typing import NamedTuple

class Symbol(NamedTuple):
    value: str

grammar = Lark(
    r"""
start : "implemente-aqui!"
""")

class LispyTransformer(InlineTransformer):
    CHARS = {
        "altmode": "\x1b",
        "backnext": "\x1f",
        "backspace": "\b",
        "call": "SUB",
        "linefeed": "\n",
        "page": "\f",
        "return": "\r",
        "rubout": "\xc7",
        "space": " ",
        "tab": "\t",
    }


from random import random, randint, uniform
import control_datos
import menus
import funciones
import parametros

racer_parametros = {"Tareos": parametros.EQUIPOS["TAREOS"],
                    "Docencios": parametros.EQUIPOS["DOCENCIOS"],
                    "Hibridos": parametros.EQUIPOS["HIBRIDOS"]}
car_parametros = {"automóvil": parametros.AUTOMOVIL, "bicicleta": parametros.BICICLETA,
                  "troncomóvil": parametros.TRONCOMOVIL, "motocicleta": parametros.MOTOCICLETA}
number_team = {0: "Tareos", 1: "Hibridos", 2: "Docencios"}
number_car = {0: "automóvil", 1: "troncomóvil", 2: "motocicleta", 3: "bicicleta"}

class Racers():
    def __init__(self, name, moneyorlevel, personalidad, cuerpo, balance,
                 exp, equipo):
        if moneyorlevel.isalpha():
            self.level = moneyorlevel
        else:
            self.money = int(moneyorlevel)
        self.experience = int(exp)
        self.name = name
        self.team = equipo
        self.personality = personalidad
        self.body = int(cuerpo)
        self.balance = int(balance)
        self.car = None
        self.time_lap = 0
        self.time_race = 0

    def __repr__(self):
        return self.name

class Cars():
    def __init__(self, name, dueno, tipo, chasis, carroceria, ruedas, aceleracion, peso):
        self.name = name
        self.owner = dueno
        self.type = tipo
        self.chassis = int(chasis)
        self.chassis_damage = 0
        self.body = int(carroceria)
        self.weight = int(peso)
        self.wheels = int(ruedas)
        self.engine = int(aceleracion)

    @property
    def chasis(self):
        return self.chassis - self.chassis_damage

    @chasis.setter
    def chasis(self, x):
        self.chassis = self.chassis * parametros.MEJORAS["CHASIS"]["EFECTO"] * x

    @property
    def carroceria(self):
        return self.body

    @carroceria.setter
    def carroceria(self, x):
        self.body = self.body * parametros.MEJORAS["CARROCERIA"]["EFECTO"] * x

    @property
    def ruedas(self):
        return self.wheels

    @ruedas.setter
    def ruedas(self, x):
        self.wheels = self.wheels * parametros.MEJORAS["RUEDAS"]["EFECTO"] * x

    @property
    def motor(self):
        return self.engine

    @motor.setter
    def motor(self, x):
        if self.type in ("automóvil", "troncomóvil"):
            self.engine = self.engine * parametros.MEJORAS["MOTOR"]["EFECTO"] * x
        else:
            self.engine = self.engine * parametros.MEJORAS["ZAPATILLAS"]["EFECTO"] * x

    def __repr__(self):
        return ("{:<31s}| Chasis:{:>5d}| Carrocería:{:>5d}|" +
                " Peso:{:>5d}| Ruedas:{:>5d}| Aceleración:{:>5d}").\
                format(self.name, self.chasis, self.carroceria,
                       self.weight, self.ruedas, self.motor)

class Tracks():
    def __init__(self, name, tipo, hielo, rocas, dificultad, vueltas, rivales, largo):
        self.name = name
        self.type = tipo
        self.ice = int(hielo)
        self.rocks = int(rocas)
        self.level = int(dificultad)
        self.enemies = rivales
        self.laps = int(vueltas)
        self.length = int(largo)

    def __repr__(self):
        return self.name

class Race():
    def __init__(self, pista, corredores, user):
        self.track = pista
        self.user = user
        self.racers = corredores + [user]
        self.losers = []
        self.laps = 0

    def continue_race(self, game, is_user):
        for racer in self.racers:
            racer.car.chassis_damage += funciones.car_damage(racer.car, self.track)
            if uniform(0, 1) <= funciones.accident(racer.car, racer, self.track, self):
                racer.car.chassis_damage = racer.car.chassis
            racer.time_lap = funciones.lap_time(racer.car, racer, self.track, self)
            racer.time_race += racer.time_lap
            if racer.car.chasis == 0:
                self.losers.append(racer)
                if racer.name == self.user.name:
                    self.racers = list(filter(lambda corredor: (corredor.car.chasis != 0), self.racers))
                    while self.laps <= self.track.laps - 1:
                        self.continue_race(game, False)
                    print("\nHas sido eliminado de la carrera debido a un accidente.",
                          "Los resultados de la carrera fueron:")
                    return self.end_race(game)
        self.racers = list(filter(lambda racer: (racer.car.chasis != 0), self.racers))
        self.laps += 1
        if self.laps == self.track.laps:
            return self.end_race(game)
        if is_user:
            self.racers.sort(key=racer_place)
            if self.user == self.racers[0]:
                self.user.money += funciones.money_per_lap(self, self.track)
            print(f"\nVuelta: {self.laps} / {self.track.laps}\nPosiciones de los corredores:")
            if funciones.velocidad_intencional(racer.car, racer, self.track) !=\
               funciones.velocidad_real(racer.car, racer, self.track, self):
                print("Tu velocidad ha sido afectada durante esta vuelta")
            else:
                print("Tu velocidad no ha sido afectada durante esta vuelta")
            if funciones.dificultad_control(self.user.car, self.user) != 0:
                print("Has tenido dificultades para controlar tu vehículo")
            if funciones.car_damage(self.user.car, self.track) != 0:
                print("Tú chasis se ha dañado!")
            if funciones.hipotermia(self, self.user, self.track) != 0:
                pritn("Has sido victima de la hipotermia debido al hielo de la pista")
            print_places(self.racers)
            if self.losers != []:
                print("Competidores descalificados:")
                for racer in self.losers:
                    print(f" - {racer.name}")

    def end_race(self, game):
        self.racers.sort(key=racer_place)
        print_places(self.racers)
        if self.user == self.racers[0]:
            money = funciones.winner_price(self.track)
            exp = funciones.winner_exp(self.user, self.track,
                                       self.racers[len(self.racers) - 1])
            print("\nFelicidades has sido el ganador de la carrera\n",
                  f"Has conseguido ${money} y {exp} puntos de experiencia")
            self.user.money += money
            self.user.experience += exp
        else:
            print("\nNos has sido el ganador, pero has ganado en diversión\n")
        for racer in (self.racers + self.losers):
            racer.time_race = 0
            racer.car.chassis_damage = 0
        return True

class Game():
    def __init__(self):
        self.user = None
        self.user_cars = []
        self.users = control_datos.load_racers()
        self.enemies = control_datos.load_enemies()
        self.cars = control_datos.load_cars()
        self.tracks = control_datos.load_tracks()

    def new_game(self):
        name, team, car, carname, isalpha = False, False, False, "", False
        while not name:
            name = check_alpha("Selecciona un nombre de usuario solo con letras y espacios:\n")
            if name:
                is_in = False
                for user in self.users:
                    if name == user.name:
                        is_in = True
                        break
                if is_in:
                    error(6)
                    name = False
        while not team:
            print("Selecciona uno de los siguientes equipos",
                  "disponibles:\n")
            menus.print_options(("Tareos", "Hibridos", "Docencios"))
            team = check_numeric("\n")
            if team:
                if int(team) in (1, 2, 3):
                    self.user = new_racer(name, number_team[int(team) - 1])
                    with open(parametros.PATHS["PILOTOS"], "a", encoding="utf-8") as file:
                        file.write(f"{name},{self.user.money},{self.user.personality}," +
                                   f"{self.user.body},{self.user.balance}," +
                                   f"{self.user.experience},{self.user.team}\n")
                else:
                    error(5)
                    team = False
        while not car:
            print("Selecciona el tipo de tu primer vehículos:\n")
            menus.print_options(("Automovil", "Troncomovil", "Motocicleta", "Bicicleta"))
            car = check_length("\n")
        while not carname:
            carname = check_alpha("Selecciona un nombre para tu vehiculo:\n")
            if carname:
                if carname in self.user_cars:
                    error(6)
                else:
                    self.user_cars.append(new_car(carname, number_car[int(car) - 1], self.user))
                    with open(parametros.PATHS["VEHICULOS"], "a", encoding="utf-8") as file:
                        file.write(f"{carname},{name},{self.user_cars[0].type}," +
                                   f"{self.user_cars[0].chassis},{self.user_cars[0].body}," +
                                   f"{self.user_cars[0].wheels},{self.user_cars[0].motor}" +
                                   f",{self.user_cars[0].weight}\n")
        del self.users

    def save_game(self):
        racers = control_datos.load_racers()
        for index, racer in zip(range(len(racers)), racers):
            if self.user.name == racer.name:
                racers.pop(index)
        control_datos.save_racers(racers + [self.user])
        control_datos.save_cars(self.cars + self.user_cars)
        print("\n-Tus datos han sido almacenados de manera exitosa-\n")

    def load_game(self):
        name = False
        while not name:
            name = check_alpha("Escribe el nombre de usuario que deseas cargar:\n")
            if name:
                is_in = False
                for user in self.users:
                    if name == user.name:
                        is_in = True
                        break
                if not is_in:
                    error(7)
                    name = False
        for usuario in self.users:
            if name == usuario.name:
                self.user = usuario
        indexs = []
        for index, vehiculo in zip(range(len(self.cars) + 1), self.cars):
            if name == vehiculo.owner:
                self.user_cars.append(self.cars[index])
                indexs.append(index)
        for index in indexs[::-1]:
            self.cars.pop(index)
        del(self.users)

    def start_race(self):
        menu_rc = menus.Menu_race_configuration()
        menu_r = menus.Menu_race("Ir a los pits", "Continuar la carrera")
        race = menu_rc.selection(self)
        if not race.continue_race(self, True):
            while True:
                if menu_r.selection(self):
                    if menu_r.option(self, race):
                        break
                else:
                    if race.continue_race(self, True):
                        break

    def buy_car(self):
        menu_b = menus.Menu_buy([("Automóvil", 500), ("Troncomóvil", 900),
                                ("Motocicleta", 370), ("Bicicleta", 1050)],
                                "Volver al menú principal")
        while True:
            if menu_b.selection(self):
                while True:
                    name = check_alpha("Selecciona un nombre para tu vehiculo:\n")
                    if name and name in self.user_cars:
                        error(6)
                        name = False
                    elif name:
                        break
                self.user_cars.append(new_car(name, number_car[menu_b.option], self.user))
                self.user.money -= menu_b.options[menu_b.option][1]
                print("\n-Compra realizada con exito-\n")
            else:
                break

    def pits(self, race):
        if self.user.car.chassis != self.user.car.carroceria:
            funciones.pits_time(self.user.car)
            self.user.car.chassis_damage = 0
        if self.user.car.type in ("automóvil", "motocicleta"):
            motor = ("Motor", parametros.MEJORAS["MOTOR"]["COSTO"])
        else:
            motor = ("Zapatillas", parametros.MEJORAS["ZAPATILLAS"]["COSTO"])
        menu_pt = menus.Menu_pits((("Chasis", parametros.MEJORAS["CHASIS"]["COSTO"]),
                                   ("Carrocería", parametros.MEJORAS["CARROCERIA"]["COSTO"]),
                                   ("Ruedas", parametros.MEJORAS["RUEDAS"]["COSTO"]),
                                   motor), "Continuar la carrera")
        while True:
            print(f"Dinero del usuario: {self.user.money}")
            if menu_pt.selection(self):
                if menu_pt.option[0] == "Chasis":
                    race.user.car.chasis = 1
                elif menu_pt.option[0] == "Carrocería":
                    race.user.car.carroceria = 1
                elif menu_pt.option[0] == "Ruedas":
                    race.user.car.ruedas = 1
                else:
                    race.user.car.motor = 1
                race.user.money -= menu_pt.option[1]
                print("\n-Compra realizada con exito-\n")
                return race.continue_race(self, True)
            else:
                return race.continue_race(self, True)

def new_car(nombre, tipo, user):
    max_min = car_parametros[tipo]
    chasis = randint(max_min["CHASIS"]["MIN"], max_min["CHASIS"]["MAX"])
    carroceria = randint(max_min["CARROCERIA"]["MIN"], max_min["CARROCERIA"]["MAX"])
    peso = randint(max_min["PESO"]["MIN"], max_min["PESO"]["MAX"])
    ruedas = randint(max_min["RUEDAS"]["MIN"], max_min["RUEDAS"]["MAX"])
    if tipo in ("troncomóvil", "bicicleta"):
        motor = randint(max_min["ZAPATILLAS"]["MIN"], max_min["ZAPATILLAS"]["MAX"])
    else:
        motor = randint(max_min["MOTOR"]["MIN"], max_min["MOTOR"]["MAX"])
    return Cars(nombre, user.name, tipo, chasis, carroceria, ruedas, motor, peso)

def new_racer(name, equipo):
    max_min = racer_parametros[equipo]
    contextura = randint(max_min["CONTEXTURA"]["MIN"], max_min["CONTEXTURA"]["MAX"])
    equilibrio = randint(max_min["EQUILIBRIO"]["MIN"], max_min["EQUILIBRIO"]["MAX"])
    personalidad = max_min["PERSONALIDAD"]
    return Racers(name, "0", personalidad, contextura, equilibrio, 0, equipo)

def select_car(all_cars, enemie):
    cars = []
    for car in all_cars:
        if car.owner == enemie.name:
            cars.append(car)
    if len(cars) != 1:
        selection = randint(0, len(cars) - 1)
    else:
        selection = 0
    return cars[selection]

def print_places(racers):
    print("{:>8s} | {:^20s}| {:>6s}| {:>6s}".format("Posición", "Corredor",
          "Tiempo vuelta", "Tiempo total"))
    for index, racer in zip(range(1, len(racers) + 1), racers):
        print("{:>8d}°| {:^20s}| {:>9d} seg| {:>6d} seg".format(index,
              racer.name, racer.time_lap, racer.time_race))

def check_alpha(mensaje):
    command = input(mensaje).strip(" ")
    if not "".join(filter(lambda character: character != " ", command)).isalpha():
        error(0)
        return False
    else:
        return command

def check_numeric(mensaje):
    command = input(mensaje).strip(" ")
    if not "".join(filter(lambda character: character != " ", command)).isnumeric():
        error(1)
        return False
    return command

def check_length(mensaje):
    command = check_numeric(mensaje)
    if command and len(command) != 1:
        error(3)
        return False
    return command

def racer_place(racer):
    return racer.time_race

def error(option):
    option1 = "El valor ingresado no contiene solo espacios y letras"
    option2 = "El valor ingresado no contiene solo numeros"
    option3 = "El nombre elegido ya lo posee otro de tus vehiculos"
    option4 = "El comando posee una longitud erronea"
    option5 = "No posees el dinero necesario para realizar esa compra"
    option6 = "El valor ingresado es mayor o menor a los valores posibles"
    option7 = "Este nombre ya lo posee otro piloto o no es válido"
    option8 = "El nombre ingresado no existe, por favor intente nuevamente"
    options = {0: option1, 1: option2, 2: option3, 3: option4, 4: option5,
               5: option6, 6: option7, 7: option8}
    print(f"\n --Error-- {options[option]}\n")


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

import os
from os import path
import speech_recognition as sr
from gtts import gTTS

def rec():
    r = sr.Recognizer()
    with sr.Microphone() as source:
        #r.adjust_for_ambient_noise(source)
        print('Say something!')
        audio = r.listen(source)

    try:
        sttTXT_org = r.recognize_google(audio, language = 'en-US')
        print("Google Speech Recognition thinks you said: " + sttTXT_org)
        return sttTXT_org
    except sr.UnknownValueError:
        print("Google Speech Recognition could not understand audio")
        return 0
    except sr.RequestError as e:
        print('Could not request results from Google Speech Recognition service; {0}'.format(e))
        return 0

def t2speech(txt):
    tts =  gTTS(text=txt,lang='en-US').save('{}.mp3'.format(txt))


from functools import reduce

VERSION_SUM = 0
PACKET_COUNT = 0

def hex_to_binary(hex_number: str, num_digits: int = 8) -> str:
    """
    Converts a hexadecimal value into a string representation
    of the corresponding binary value
    Args:
        hex_number: str hexadecimal value
        num_digits: integer value for length of binary value.
                    defaults to 8
    Returns:
        string representation of a binary number 0-padded
        to a minimum length of <num_digits>
    """
    return str(bin(int(hex_number, 16)))[2:].zfill(num_digits)

def build_packets_from_sequence(sequence, add_to_global=True):
    # build Packets until the sequence ends
    packets = []
    while len(sequence) > 0:
        type_id = int(sequence[3:6], 2)
        if type_id == 4:
            count = 0
            while True:
                val = sequence[6 + 5 * count]
                if val == "0":
                    break
                else:
                    count += 1
            packets.append(Packet(sequence[: 6 + (count + 1) * 5], add_to_global))
            sequence = sequence[6 + (count + 1) * 5 :]
        else:
            length_type_id = sequence[6]
            if length_type_id == "0":
                length_of_subseq_packet = sequence[7:22]
                length_of_subseq_packet = int(length_of_subseq_packet, 2)
                new_packet = Packet(sequence[0 : 22 + length_of_subseq_packet], add_to_global)
                packets.append(new_packet)
                sequence = sequence[22 + length_of_subseq_packet :]
            elif length_type_id == "1":
                number_of_subseq_packet = sequence[7:18]
                number_of_subseq_packet = int(number_of_subseq_packet, 2)
                new_packets, consumed = build_n_number_of_packets(
                    sequence[18:], number_of_subseq_packet, False
                )
                del new_packets
                # packets.extend(new_packets)
                new_packet = Packet(sequence[: 18 + consumed], add_to_global)
                packets.append(new_packet)
                sequence = sequence[18 + consumed :]
    return packets

def build_n_number_of_packets(sequence, n, add_to_global):
    # Build 'n' number of packets from the sequence
    packets = []
    sequence_pointer = 0
    while len(packets) < n and sequence:
        type_id = int(sequence[3:6], 2)
        if type_id == 4:
            count = 0
            while True:
                val = sequence[6 + 5 * count]
                if val == "0":
                    break
                else:
                    count += 1
            packets.append(Packet(sequence[: 6 + (count + 1) * 5], add_to_global))
            sequence_pointer += 6 + (count + 1) * 5
            sequence = sequence[6 + (count + 1) * 5 :]
        else:
            length_type_id = sequence[6]
            if length_type_id == "0":
                length_of_subseq_packet = sequence[7:22]
                length_of_subseq_packet = int(length_of_subseq_packet, 2)
                new_packet = Packet(sequence[: 22 + length_of_subseq_packet], add_to_global)
                packets.append(new_packet)
                sequence = sequence[22 + length_of_subseq_packet :]
                sequence_pointer += 22 + length_of_subseq_packet
            elif length_type_id == "1":
                number_of_subseq_packet = sequence[7:18]
                number_of_subseq_packet = int(number_of_subseq_packet, 2)
                new_packets, consumed = build_n_number_of_packets(
                    sequence[18:], number_of_subseq_packet, False
                )
                del new_packets
                new_packet = Packet(sequence[: 18 + consumed], add_to_global)
                packets.append(new_packet)
                sequence = sequence[18 + consumed :]
                sequence_pointer += consumed + 18
    return packets, sequence_pointer

class Packet(object):
    def __init__(self, binary_data, add_to_global=True):
        self.binary_data = binary_data
        self.version = int(binary_data[0:3], 2)

        if add_to_global:
            global VERSION_SUM, PACKET_COUNT
            VERSION_SUM += self.version
            PACKET_COUNT += 1

        self.type_id = int(binary_data[3:6], 2)
        print(f"Packet; Initialized; type:{self.type_id}; version:{self.version}")
        if self.type_id == 4:
            val = ""
            stop = False
            count = 0
            while not stop:
                start_index = 6 + count * 5
                chunk = binary_data[start_index : start_index + 5]
                val += chunk[1:]
                if chunk[0] == "0":
                    break
                else:
                    count += 1
            self.literal_vals = val
            # print(f"literal value: {val} == {int(val, 2)}, version: {self.version}")
        else:
            length_type_id = binary_data[6]
            if length_type_id == "0":
                length_of_subseq_packet = binary_data[7:22]
                length_of_subseq_packet = int(length_of_subseq_packet, 2)
                self.child_packets = build_packets_from_sequence(
                    binary_data[22 : 22 + length_of_subseq_packet], add_to_global
                )
            elif length_type_id == "1":
                number_of_subseq_packet = binary_data[7:18]
                number_of_subseq_packet = int(number_of_subseq_packet, 2)
                # print(f"here: {binary_data[18:]}, {number_of_subseq_packet}")
                self.child_packets, _ = build_n_number_of_packets(
                    binary_data[18:], number_of_subseq_packet, add_to_global
                )

def process_subpacket_values(packet: Packet):
    if hasattr(packet, 'literal_vals'):
        return int(packet.literal_vals, 2)

    if not hasattr(packet, 'child_packets'):
        return 0
    child_packets = packet.child_packets

    vals = []
    for child_packet in child_packets:
        val = process_subpacket_values(child_packet)
        vals.append(val)

    if packet.type_id == 0:
        return sum(vals)
    elif packet.type_id == 1:
        return reduce(lambda x, y: x*y, vals)
    elif packet.type_id == 2:
        return min(vals)
    elif packet.type_id == 3:
        print(vals, packet.binary_data)
        return max(vals)
    elif packet.type_id == 5:
        return 1 if vals[0] > vals[1] else 0
    elif packet.type_id == 6:
        return 1 if vals[0] < vals[1] else 0
    elif packet.type_id == 7:
        return 1 if vals[0] == vals[1] else 0

if __name__ == "__main__":
    with open("input", "r") as fh:
        line = fh.readline()

    # line = "C200B40A82"  #3
    line = "04005AC33890"  # 54
    # line = "880086C3E88112" # 7
    # line = "CE00C43D881120"  # 9
    # line = "D8005AC2A8F0"   # 1
    # line = "F600BC2D8F"  # 0
    # line = "9C005AC2F8F0" # 0
    # line = "9C0141080250320F1802104A08" # 1

    bin_val = hex_to_binary(line)
    if len(bin_val) % 4:
        bin_val = "0" * (4 - len(bin_val) % 4) + bin_val
    packet = Packet(bin_val)

    print(f"Packets: {PACKET_COUNT}, VERSION_SUM: {VERSION_SUM}")
    result = process_subpacket_values(packet)
    print(result)


from __future__ import annotations
import sys
import math
from typing import Any, Sequence, TYPE_CHECKING, Callable, Iterable
import logging
from functools import lru_cache
import click
import pydsdl
import pycyphal
from pycyphal.transport import TransferFrom
from pycyphal.presentation import Subscriber
import yakut
from yakut.param.formatter import Formatter
from yakut.util import convert_transfer_metadata_to_builtin
from yakut.subject_specifier_processor import process_subject_specifier, SubjectResolver
from ._sync import Synchronizer, SynchronizerFactory

if TYPE_CHECKING:
    import pycyphal.application

_logger = yakut.get_logger(__name__)

SYNC_MONOCLUST_TOLERANCE_MINMAX_TS_FIELD = 1e-6, 10.0
"""
Assume that externally provided timestamp is accurate at least for high-frequency topics.
"""

SYNC_MONOCLUST_TOLERANCE_MINMAX_TS_ARRIVAL = 0.02, 60.0
"""
A large minimum is needed due to low arrival timestamping accuracy.
This may be especially bad on Windows where the timestamping resolution may be as low as ~16 ms,
so the minimum tolerance should not be lower than that.
"""

class Config:
    def __init__(self) -> None:
        self._synchronizer_factory: SynchronizerFactory | None = None

    def set_synchronizer_factory(self, val: SynchronizerFactory) -> None:
        if self._synchronizer_factory is not None:
            raise click.UsageError("Cannot use more than one synchronizer")
        self._synchronizer_factory = val
        _logger.debug("Using synchronizer factory: %r", val)

    def get_synchronizer_factory(self) -> SynchronizerFactory:
        if self._synchronizer_factory is None:
            from ._sync_async import make_sync_async

            self.set_synchronizer_factory(make_sync_async)
        assert self._synchronizer_factory is not None
        return self._synchronizer_factory

def _has_field(model: pydsdl.CompositeType, name: str, type_full_name: str) -> bool:
    for field in model.fields:
        dt = field.data_type
        if field.name == name and isinstance(dt, pydsdl.CompositeType) and dt.full_name == type_full_name:
            return True
    return False

def _ensure_timestamp_field_synchronization_is_possible(model: pydsdl.CompositeType) -> None:
    if not _has_field(model, "timestamp", "uavcan.time.SynchronizedTimestamp"):
        raise click.ClickException(
            f"Synchronization on timestamp field is not possible for {model} because there is no such field. "
            f"Please use another synchronization policy or use only timestamped data types."
        )

def _handle_option_synchronizer_monoclust_timestamp_field(
    ctx: click.Context,
    _param: click.Parameter,
    value: float | None,
) -> None:
    if value is not None:
        from pycyphal.presentation.subscription_synchronizer import get_timestamp_field
        from ._sync_monoclust import make_sync_monoclust

        value = float(value)
        tol = SYNC_MONOCLUST_TOLERANCE_MINMAX_TS_FIELD if not math.isfinite(value) else (value, value)
        _logger.debug("Configuring field timestamp monoclust synchronizer with tolerance=%r", tol)

        def fac(subs: Iterable[Subscriber[Any]]) -> Synchronizer:
            subs = list(subs)
            for s in subs:
                _ensure_timestamp_field_synchronization_is_possible(pycyphal.dsdl.get_model(s.dtype))
            return make_sync_monoclust(subs, f_key=get_timestamp_field, tolerance_minmax=tol)

        ctx.ensure_object(Config).set_synchronizer_factory(fac)

def _handle_option_synchronizer_monoclust_timestamp_arrival(
    ctx: click.Context,
    _param: click.Parameter,
    value: float | None,
) -> None:
    if value is not None:
        from pycyphal.presentation.subscription_synchronizer import get_local_reception_timestamp
        from ._sync_monoclust import make_sync_monoclust

        value = float(value)
        tol = SYNC_MONOCLUST_TOLERANCE_MINMAX_TS_ARRIVAL if not math.isfinite(value) else (value, value)
        _logger.debug("Configuring arrival timestamp monoclust synchronizer; tolerance=%r", tol)
        ctx.ensure_object(Config).set_synchronizer_factory(
            lambda subs: make_sync_monoclust(subs, f_key=get_local_reception_timestamp, tolerance_minmax=tol)
        )

def _handle_option_synchronizer_transfer_id(ctx: click.Context, _param: click.Parameter, value: bool) -> None:
    if value:
        from ._sync_transfer_id import make_sync_transfer_id

        _logger.debug("Configuring transfer-ID synchronizer")
        ctx.ensure_object(Config).set_synchronizer_factory(make_sync_transfer_id)

@yakut.subcommand(aliases=["sub", "s"])
@click.argument("subject", type=str, nargs=-1)
@click.option(
    "--with-metadata/--no-metadata",
    "+M/-M",
    default=not sys.stdout.isatty(),
    help="""
When enabled, each message object is prepended with an extra field named `_meta_`.
Enabled by default unless stdout is a tty.
""",
)
@click.option(
    "--count",
    "-N",
    type=int,
    metavar="CARDINAL",
    help=f"""
Exit automatically after this many messages (or synchronous message groups) have been received. No limit by default.
""",
)
@click.option(
    "--redraw",
    "--no-scroll",
    "-R",
    is_flag=True,
    help="Clear terminal before printing output. This option only has effect if stdout is a tty.",
)
@click.option(
    "--sync-monoclust-field",
    "--smcf",
    callback=_handle_option_synchronizer_monoclust_timestamp_field,
    expose_value=False,
    type=float,
    is_flag=False,
    flag_value=float("nan"),
    help=f"""
Use the monotonic clustering synchronizer with the message timestamp field as the clustering key.
All data types shall be timestamped for this to work.
The optional value is the synchronization tolerance in seconds; autodetect if not specified.
""",
)
@click.option(
    "--sync-monoclust-arrival",
    "--smca",
    "--sync",  # This is currently the default because it works with any data type.
    callback=_handle_option_synchronizer_monoclust_timestamp_arrival,
    expose_value=False,
    type=float,
    is_flag=False,
    flag_value=float("nan"),
    help=f"""
Use the monotonic clustering synchronizer with the local arrival timestamp as the clustering key.
Works with all data types but may perform poorly depending on the local timestamping accuracy and system latency.
The optional value is the synchronization tolerance in seconds; autodetect if not specified.
""",
)
@click.option(
    "--sync-transfer-id",
    "--stid",
    callback=_handle_option_synchronizer_transfer_id,
    expose_value=False,
    is_flag=True,
    help=f"""
Use the transfer-ID synchronizer.
Messages that originate from the same node AND share the same transfer-ID will be grouped together.
""",
)
@yakut.pass_purser
@yakut.asynchronous(interrupted_ok=True)
async def subscribe(
    purser: yakut.Purser,
    subject: tuple[str, ...],
    with_metadata: bool,
    count: int | None,
    redraw: bool,
) -> None:
    """
    Subscribe to specified subjects and print messages to stdout.
    It is recommended to make this node anonymous (i.e., without a node-ID)
    to avoid additional traffic on the network from this tool.

    The arguments are a list of message data type names prepended with the subject-ID;
    the subject-ID may be omitted if the data type defines a fixed one;
    or the type can be omitted to engage automatic type discovery
    (discovery may fail if the local node is anonymous as it will be unable to issue RPC-service requests).
    The short data type name is case-insensitive for convenience.
    The accepted forms are:

    \b
        SUBJECT_ID:TYPE_NAME[.MAJOR[.MINOR]]
        TYPE_NAME[.MAJOR[.MINOR]]
        SUBJECT_ID

    The output documents (YAML/JSON/etc depending on the chosen format) will contain one message object each,
    unless synchronization is enabled via --sync-*.
    In that case, each output document will contain a complete synchronized group of messages (ordering retained).
    Synchronous subscription is intended for subscribing to a group of coupled subjects like coupled sensor feeds.
    More on subscription synchronization is available in the PyCyphal docs.

    Each received message or synchronized group is emitted to stdout as a key-value mapping,
    where the keys are subject-IDs and values are the received message objects.

    Examples:

    \b
        yakut sub 33:uavcan.si.unit.angle.scalar --with-metadata --count=1
        yakut sub 33 42 5789 --sync-monoclust-arrival=0.1
        yakut sub uavcan.node.heartbeat
        y sub 1220 1230 1240 1250 --sync-monoclust

    Extracting a specific field, sub-object, data manipulation:

    \b
        y sub uavcan.node.heartbeat | jq '.[].health.value'
        y sub uavcan.node.heartbeat +M | jq '.[]|[._meta_.transfer_id, ._meta_.timestamp.system]'
    """
    config = click.get_current_context().ensure_object(Config)
    try:
        from pycyphal.application import Node
    except ImportError as ex:
        from yakut.cmd.compile import make_usage_suggestion

        raise click.ClickException(make_usage_suggestion(ex.name))

    finalizers: list[Callable[[], None]] = []
    try:
        _logger.debug("subject=%r, with_metadata=%r, count=%r", subject, with_metadata, count)
        if count is not None and count <= 0:
            _logger.warning("Nothing to do because count=%s", count)
            return

        count = count if count is not None else sys.maxsize
        formatter = purser.make_formatter()

        # Node construction should be delayed as much as possible to avoid unnecessary interference
        # with the bus and hardware. This is why we use the factory here instead of constructing the node eagerly.
        @lru_cache(None)
        def get_node() -> Node:
            node = purser.get_node("subscribe", allow_anonymous=True)
            finalizers.append(node.close)
            return node

        subscribers: list[Subscriber[Any]] = await _make_subscribers(subject, get_node)
        finalizers += [s.close for s in subscribers]
        if len(subscribers) == 0:
            _logger.warning("Nothing to do because no subjects are specified")
            return
        synchronizer = config.get_synchronizer_factory()(subscribers)

        # The node is closed through the finalizers at exit.
        # Note that we can't close the node before closing the subscribers to avoid resource errors inside PyCyphal.
        node = get_node()
        if node.id is not None:
            _logger.info("It is recommended to use an anonymous node with this command")
        node.start()
        try:
            await _run(synchronizer, formatter, with_metadata=with_metadata, count=count, redraw=redraw)
        finally:
            if _logger.isEnabledFor(logging.INFO):
                _logger.info("%s", node.presentation.transport.sample_statistics())
                for sub in subscribers:
                    _logger.info("% 4s: %s", sub.port_id, sub.sample_statistics())
    finally:
        pycyphal.util.broadcast(finalizers[::-1])()

async def _make_subscribers(
    specifiers: Sequence[str],
    node_provider: Callable[[], "pycyphal.application.Node"],
) -> list[Subscriber[Any]]:
    subject_resolver: SubjectResolver | None = None

    def get_resolver() -> SubjectResolver:
        nonlocal subject_resolver
        if subject_resolver is None:
            node = node_provider()
            if node.id is None:
                raise click.ClickException(
                    f"Cannot use automatic discovery because the local node is anonymous, "
                    f"so it cannot access the introspection services on remote nodes. "
                    f"You need to either fully specify the subjects explicitly or assign a local node-ID."
                )
            subject_resolver = SubjectResolver(node)
        return subject_resolver

    try:
        id_types = [await process_subject_specifier(ds, get_resolver) for ds in specifiers]
        # Construct the node only after we have verified that the specifiers are valid and dtypes/ids are resolved.
        return [node_provider().make_subscriber(dtype, subject_id) for subject_id, dtype in id_types]
    finally:
        if subject_resolver:
            subject_resolver.close()

async def _run(synchronizer: Synchronizer, formatter: Formatter, with_metadata: bool, count: int, redraw: bool) -> None:
    def process_group(group: tuple[tuple[tuple[Any, TransferFrom] | None, Subscriber[Any]], ...]) -> None:
        nonlocal count
        outer: dict[int, dict[str, Any]] = {}
        for maybe_msg_meta, subscriber in group:
            if maybe_msg_meta is None:
                continue  # Asynchronous mode.
            msg, meta = maybe_msg_meta
            assert isinstance(meta, TransferFrom) and isinstance(subscriber, Subscriber)
            bi: dict[str, Any] = {}  # We use updates to ensure proper dict ordering: metadata before data
            if with_metadata:
                bi.update(convert_transfer_metadata_to_builtin(meta, dtype=subscriber.dtype))
            bi.update(pycyphal.dsdl.to_builtin(msg))
            outer[subscriber.port_id] = bi

        if redraw:
            click.clear()
        sys.stdout.write(formatter(outer))
        sys.stdout.flush()
        count -= 1
        if count <= 0:
            _logger.debug("Reached the specified synchronized group count, stopping")
            raise _Break

    try:
        await synchronizer(process_group)
    except _Break:
        pass

class _Break(Exception):
    pass


import requests

KEY = ''

gbookurl="https://www.googleapis.com/books/v1/volumes?q=isbn:%s&key=" + KEY

def getData(urlRequest):
    r = requests.get(url = urlRequest)
    try:
        json = r.json()
        #descricao = r.json()["items"][0]["volumeInfo"]["description"]
        if ("error" in json):
            print (json["error"]["errors"][0]["reason"])
        else:
            webReaderLink = json["items"][0]["accessInfo"]["webReaderLink"]
            accessViewStatus = json["items"][0]["accessInfo"]["accessViewStatus"]
        if (accessViewStatus != "NONE"):
            return webReaderLink
    except KeyboardInterrupt:
        exit()
    except:
        pass
        #print (urlRequest)

fsuccs = open("succ.csv", "w")
ferrors = open("error.csv", "w")
base = open("livros.csv")
isbns = []
errors = []
succs = []

for livro in base:
    if livro:
        stripped = livro.strip("\n").split(",")
        current_isbn = stripped[-1]
        if current_isbn and current_isbn not in isbns:
            isbns.append(current_isbn)
            print (current_isbn)
            urlRequest = gbookurl % current_isbn
            webview = getData(urlRequest)
            if (webview):
                line = stripped[0] + "," + current_isbn + "," + webview + "\n"
                succs.append(line)
                print (line)
            else:
                line = stripped[0] + "," + current_isbn + "," + urlRequest + "\n"
                errors.append(line)

fsuccs.writelines(succs)
ferrors.writelines(errors)
fsuccs.close()
ferrors.close()

#print (descricao)
#print (webview)


import numpy as np

def calc_cutoff(neighs, stdv_multiplier):
    value = neighs
    arr = np.array(value)
    mean = np.mean(arr)
    sd = np.std(arr)

    return mean + stdv_multiplier * sd

def variance(clusters):
    variances = []

    for key in clusters:
        if len(clusters[key].costs) > 0:
            var = np.var(clusters[key].costs)

            if str(var) != 'nan' and var != 0:
                variances.append(float(var))
                clusters[key].var = var

    return variances


class Solution:
    # @param root, a tree node
    # @return a boolean

    def traversal(self, root):
        if root is None:
            return 1
        left = self.traversal(root.left)
        right = self.traversal(root.right)
        if left is False or right is False:
            return False
        left_depth = 1 + left
        right_depth = 1 + right
        if abs(left_depth-right_depth) > 1:
            return False
        return max(left_depth, right_depth)

    def isBalanced(self, root):
        if self.traversal(root) == False:
            return False
        else:
            return True


#!/usr/bin/env python3
"""Program that creates a tensorflow layer that includes
L2 regularization"""
import tensorflow as tf

def l2_reg_create_layer(prev, n, activation, lambtha):
    """Function that creates a tensorflow layer that includes
    L2 regularization"""
    init = tf.contrib.layers.variance_scaling_initializer(mode="FAN_AVG")
    reg = tf.contrib.layers.l2_regularizer(lambtha)
    mod = tf.layers.Dense(n, activation, kernel_initializer=init,
                          kernel_regularizer=reg, name='layer')
    return mod(prev)


def get_client_data():
    cedula = input("Ingrese su cedula: ")
    while not cedula.isnumeric():
        cedula = input("Ingreso Invalido. Ingrese su cedula: ")

    tipo_de_vehiculo = input("Ingrese el tipo del vehiculo \n A. Automatico \n S. Sincronico \n -->  ").upper()
    while not tipo_de_vehiculo.isalpha() or not tipo_de_vehiculo == "A" and not tipo_de_vehiculo == "S":
        tipo_de_vehiculo = input("Ingreso Invalido. Ingrese el tipo del vehiculo \n A. Automatico \n S. Sincronico \n -->  ")

    numero_horas = input("Cuantas horas va a tomar?: ")
    while not numero_horas.isnumeric():
        numero_horas = input("Ingreso Invalido. Ingrese cuantas horas va a tomar")
    numero_horas = int(numero_horas)

    cliente = {
        "Cedula": cedula,
        "Tipo de Vehiculo": tipo_de_vehiculo,
        "Horas a tomar": numero_horas
    }
    return cliente

def get_subtotal(cliente, vehiculos_dict):
    subtotal = 0
    subtotal += (vehiculos_dict.get(cliente.get("Tipo de Vehiculo")).get("price/hour") * cliente.get("Horas a tomar"))
    return subtotal

def get_discount(cliente, subtotal):
    discount = 0
    if cliente.get("Horas a tomar") > 3:
        discount += subtotal * 0.15
    return discount

def get_total(discount, subtotal):
    total = subtotal - discount
    return total

def get_receipt(cliente, vehiculos_dict, total, discount):
    print("--------FACTURA--------")
    print(f"Cedula: {cliente.get('Cedula')}")
    print(f"Tipo de Vehiculo: {vehiculos_dict.get(cliente.get('Tipo de Vehiculo')).get('description')}")
    print("-----------------------")
    print(f"Monto total: {total}")
    print(f"Descuento otorgado: {discount}")

def get_final_day_data(clientes, num_clientes):
    contA = 0
    contS = 0
    contCD = 0
    pago_automaticos = 0
    pago_sincronicos = 0
    for cliente in clientes:
        if cliente.get("Tipo de Vehiculo") == "A":
            contA += 1
            pago_automaticos += cliente.get("Monto Total a Pagar")
        if cliente.get("Tipo de Vehiculo") == "S":
            contS += 1
            pago_sincronicos += cliente.get("Monto Total a Pagar")
        if cliente.get("Descuento Otorgado") != 0:
            contCD += 1

    print("------FINAL DAY------")
    print(f"Numero total de clientes: {num_clientes}")
    print(f"Clientes totales para vehiculos Automaticos: {contA}")
    print(f"Clientes totales para vehiculos Sincronicos: {contS}")
    print(f"Clientes totales con descuento: {contCD}")
    if contA == 0:
        print("No hay pagos en Automatico")
    else:
        print(f"Promedio de facturacion en vehiculos automaticos: {pago_automaticos/contA}")
    if contS == 0:
        print("No hay pagos en Sincronico")
    else:
        print(f"Promedio de facturacion en vehiculos sincronicos: {pago_sincronicos/contS}")

def main():
    vehiculos_dict ={
        "A": {
            "description": "Automatico",
            "price/hour": 2500
        },
        "S": {
            "description": "Sincronico",
            "price/hour": 3500
        }
    }

    clientes = []

    while True:
        print("------BIENVENIDO------")
        print()
        cliente = get_client_data()
        clientes.append(cliente)
        subtotal = get_subtotal(cliente, vehiculos_dict)
        discount = get_discount(cliente, subtotal)
        total = get_total(discount, subtotal)
        get_receipt(cliente, vehiculos_dict, total, discount)
        cliente["Descuento Otorgado"] = discount
        cliente["Monto Total a Pagar"] = total

        keep_adding_clients = input("Que desea realizar? \n 1. Agregar otro cliente \n 2. Salir \n --> ")
        while not keep_adding_clients.isnumeric() or not int(keep_adding_clients) in range (1, 3):
            keep_adding_clients = input("Ingreso Invalido. Que desea realizar? \n 1. Agregar otro cliente \n 2. Salir \n --> ")

        if keep_adding_clients == "2":
            break
    get_final_day_data(clientes, len(clientes))
main()


# -*- coding: utf-8 -*-
"""
Created on Thu Jun 28 16:26:23 2018

@author: Joseph
"""

import tensorflow as tf
import math
from six.moves import xrange
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.training import moving_averages
def batch_normalization(logits, scale, offset, isTraining = False, name="bn"):
	mean, var = tf.nn.moments(logits, [0, 1, 2])
	moving_mean_shape = mean.get_shape()
	moving_var_shape = var.get_shape()
	moving_mean = tf.get_variable('moving_mean',moving_mean_shape,initializer=tf.zeros_initializer,trainable=False)
	moving_var = tf.get_variable('moving_var', moving_var_shape,initializer=tf.ones_initializer,trainable=False)
	moving_mean = moving_averages.assign_moving_average(moving_mean,mean,0.95)
	moving_var = moving_averages.assign_moving_average(moving_var,var,0.95)
	mean, var = control_flow_ops.cond(isTraining, lambda:(mean,var), lambda:(moving_mean, moving_var))
	output = tf.nn.batch_normalization(logits, mean, var, offset, scale, variance_epsilon=1e-5)
	return output

def get_conv_weights(weight_shape, sess, name="get_conv_weights"):
	#return math.sqrt(2 / (9.0 * 64)) * sess.run(tf.truncated_normal(weight_shape))
	return sess.run(tf.truncated_normal(weight_shape,stddev=0.1))

def get_bn_weights(weight_shape, clip_b, sess, name="get_bn_weights"):
	weights = get_conv_weights(weight_shape, sess)
	#return clipping(weights, clip_b)
	return  weights

def clipping(A, clip_b, name="clipping"):
	h, w = A.shape
	for i in xrange(h):
		for j in xrange(w):
			if A[i,j] >= 0 and A[i,j] < clip_b:
				A[i,j] = clip_b
			elif A[i,j] > -clip_b and A[i,j] < 0:
				A[i,j] = -clip_b
	return A


#
# @lc app=leetcode id=20 lang=python3
#
# [20] Valid Parentheses
#
# https://leetcode.com/problems/valid-parentheses/description/
#
# algorithms
# Easy (35.68%)
# Total Accepted:    526.8K
# Total Submissions: 1.5M
# Testcase Example:  '"()"'
#
# Given a string containing just the characters '(', ')', '{', '}', '[' and
# ']', determine if the input string is valid.
#
# An input string is valid if:
#
#
# Open brackets must be closed by the same type of brackets.
# Open brackets must be closed in the correct order.
#
#
# Note that an empty string is also considered valid.
#
# Example 1:
#
#
# Input: "()"
# Output: true
#
#
# Example 2:
#
#
# Input: "()[]{}"
# Output: true
#
#
# Example 3:
#
#
# Input: "(]"
# Output: false
#
#
# Example 4:
#
#
# Input: "([)]"
# Output: false
#
#
# Example 5:
#
#
# Input: "{[]}"
# Output: true
#
#
#

class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        mapping = {'(': ')', '{': '}', '[': ']'}

        for c in s:
            if c in '([{':
                stack.append(mapping[c])
            else:
                if not stack:
                    return False
                top = stack.pop()
                if c != top:
                    return False
        return False if stack else True

def assert_eq(actual, expected):
    if actual != expected:
        raise AssertionError('expected: %s, actual: %s' % (expected, actual))

def test(input_, output):
    assert_eq(Solution().isValid(input_), output)

if __name__ == '__main__':
    test('', True)
    test('{}', True)
    test('[]', True)
    test('[[[]]]', True)
    test('[[[]]', False)
    test('[]]', False)
    test('[{()}]', True)
    test('[()(){([])}]', True)


import math
PI=3.1415927
from math import sqrt

def trans_deg2rar(angle):       # a function to convert degree to radian
    return angle*PI/180.0

def trans_rar2deg(radian_angle):   #a function to convert radian to degree
    return radian_angle*180.0/PI

def get_car_coo(lon,lat):          #using radian
    x=math.cos(lon)*math.cos(lat)
    y=math.cos(lat)*math.sin(lon)
    z=math.sin(lat)
    return x,y,z

def get_sph_cor(x,y,z):    #using radian
    lon=0
    if(x==0 and y>0):
        lon=PI/2
    elif(x==0 and y<0):
        lon=3*PI/2
    elif(x==0 and y==0):
        print ("error")
        return
    elif(x>0 and y==0):
        lon=0
    elif(x>0 and y>0):
        lon=math.atan(float(y)/float(x))
    elif(x>0 and y<0):
        lon=2*PI+math.atan(float(y)/float(x))
    elif(x<0 and y==0):
        lon=PI
    elif(x<0 and y>0):
        lon=PI+math.atan(float(y)/float(x))
    elif(x<0 and y<0):
        lon=PI+math.atan(float(y)/float(x))

    lat=PI/2-math.acos(z/1.0)

    return lon,lat

def get_relative_sph_cor(direction,degree_per_move):    #using radian
    lon=0
    lat=0
    lon_move=math.atan(math.tan(trans_deg2rar(degree_per_move))/sqrt(2))
    lat_move=math.atan(math.tan(trans_deg2rar(degree_per_move))/sqrt(2+math.tan(trans_deg2rar(degree_per_move))**2))

    if not degree_per_move>0:
        print("wrong")
        return

    if(direction==0):
        lon=0
        lat+=trans_deg2rar(degree_per_move)
        return lon,lat
    elif(direction==1):
        lon+=2*PI-lon_move
        lat+=lat_move
        return lon,lat
    elif(direction==2):
        lon+=2*PI-trans_deg2rar(degree_per_move)
        lat=0
        return lon,lat
    elif(direction==3):
        lon+=2*PI-lon_move
        lat-=lat_move
        return lon,lat
    elif(direction==4):
        lon=0
        lat-=trans_deg2rar(degree_per_move)
        return lon,lat
    elif(direction==5):
        lon+=lon_move
        lat-=lat_move
        return lon,lat
    elif(direction==6):
        lon+=trans_deg2rar(degree_per_move)
        lat=0
        return lon,lat
    elif(direction==7):
        lon+=lon_move
        lat+=lat_move
        return lon,lat
    elif(direction==8):
        lon=0
        lat=0
        return lon,lat

def generate_vector(x,y,z):
    vector=[[1.0,1.0,1.0],[1.0,1.0,1.0],[1.0,1.0,1.0]]
    if(z==0):
        vector3_x=0
        vector3_y=0
        vector3_z=1
    elif(z<0):
        vector3_x=x
        vector3_y=y
        vector3_z=-((x*x+y*y)/z)
    elif(z>0):
        vector3_x = -x
        vector3_y = -y
        vector3_z = ((x * x + y * y) / z)
    vector3_real=sqrt(vector3_x**2+vector3_y**2+vector3_z**2)
    vector[0][0] = x
    vector[0][1] = y
    vector[0][2]=z
    vector[1][0]=- y / sqrt(x * x + y * y)
    vector[1][1]=x / sqrt(x * x + y * y)
    vector[1][2]=0
    vector[2][0]=vector3_x/vector3_real
    vector[2][1]=vector3_y/vector3_real
    vector[2][2]=vector3_z/vector3_real
    return vector

def get_absolute_car_coo(x,y,z,vector):
    x_real=x*vector[0][0]+y*vector[1][0]+z*vector[2][0]
    y_real=x*vector[0][1]+y*vector[1][1]+z*vector[2][1]
    z_real=x*vector[0][2]+y*vector[1][2]+z*vector[2][2]
    return x_real,y_real,z_real

def move_view(cur_lon, cur_lat, direction, degree_per_step):   #default R equals 1,don't change it
    if (cur_lat == 90.0):
        cur_lat = 89.9999999999999
    if (cur_lat == -90.0):
        cur_lat = -89.9999999999999
    relative_lon,relative_lat=get_relative_sph_cor(direction,degree_per_step)
    relative_x,relative_y,relative_z=get_car_coo(relative_lon,relative_lat)
    cur_x,cur_y,cur_z=get_car_coo(trans_deg2rar(cur_lon),trans_deg2rar(cur_lat))
    vector=generate_vector(cur_x,cur_y,cur_z)
    absolute_x,absolute_y,absolute_z=get_absolute_car_coo(relative_x,relative_y,relative_z,vector)
    new_lon,new_lat=get_sph_cor(absolute_x,absolute_y,absolute_z)
    new_lon= trans_rar2deg(new_lon)
    new_lat= trans_rar2deg(new_lat)

    if new_lon > 360.0:
        print(s)
    if new_lon < 0.0:
        print(a)

    if new_lon > 180.0:
        new_lon -= 360.0

    return new_lon,new_lat


import settings

class Fighter:

    def __init__(self, hp, defense, power, xp, death_function=None):
        self.base_max_hp = hp
        self.hp = hp
        self.base_defense = defense
        self.base_power = power
        self.xp = xp
        self.death_function = death_function

    @property
    def power(self):
        bonus = sum(equipment.power_bonus for
                    equipment in get_all_equipped(self.owner))
        return self.base_power + bonus

    @property
    def defense(self):
        bonus = sum(equipment.defense_bonus for
                    equipment in get_all_equipped(self.owner))
        return self.base_defense + bonus

    @property
    def max_hp(self):
        bonus = sum(equipment.max_hp_bonus for
                    equipment in get_all_equipped(self.owner))
        return self.base_max_hp + bonus

    def attack(self, target):
        damage = self.power - target.fighter.defense

        if damage > 0:
            print(self.owner.name.capitalize() + ' attacks ' +
                  target.name + ' for ' + str(damage) + ' hit points.')
            target.fighter.take_damage(damage)
        else:
            print(self.owner.name.capitalize() + ' attacks ' +
                  target.name + ' but it has no effect.')

    def take_damage(self, damage):
        if damage > 0:
            self.hp -= damage
            if self.hp <= 0:
                function = self.death_function
                if function is not None:
                    function(self.owner)
                if self.owner != settings.player:
                    settings.player.fighter.xp += self.xp

    def heal(self, amount):
        self.hp += amount
        if self.hp > self.max_hp:
            self.hp = self.max_hp

def get_all_equipped(obj):
    if obj == settings.player:
        equipped_list = []
        for item in settings.inventory:
            if item.equipment and item.equipment.is_equipped:
                equipped_list.append(item.equipment)
        return equipped_list
    else:
        return []


import pytest
import pytest_parallel
import os

import maia.pytree        as PT

import maia.io      as MIO
import maia.utils   as MU
import maia.factory as MF

from maia.algo.dist import convert_s_to_u, convert_s_to_ngon

ref_dir = os.path.join(os.path.dirname(__file__), 'references')

@pytest.mark.parametrize("subset_output_loc", ["FaceCenter", "Vertex"])
@pytest_parallel.mark.parallel([1,3])
def test_s2u(comm, subset_output_loc, write_output):
  mesh_file = os.path.join(MU.test_utils.mesh_dir,  'S_twoblocks.yaml')
  ref_file  = os.path.join(ref_dir,     f'U_twoblocks_{subset_output_loc.lower()}_subset_s2u.yaml')

  dist_treeS = MIO.file_to_dist_tree(mesh_file, comm)

  subset_loc = {key: subset_output_loc for key in ['BC_t', 'GC_t']}
  dist_treeU = convert_s_to_u(dist_treeS, 'NGON_n', comm, subset_loc)

  for zone in PT.iter_all_Zone_t(dist_treeU):
    assert PT.Zone.Type(zone) == 'Unstructured'
    for node in PT.get_nodes_from_label(zone, 'BC_t') + PT.get_nodes_from_label(zone, 'GridConnectivity_t'):
      assert PT.Subset.GridLocation(node) == subset_output_loc

  # Compare to reference
  ref_tree = MIO.file_to_dist_tree(ref_file, comm)
  for zone in PT.iter_all_Zone_t(dist_treeU):
    ref_zone = PT.get_node_from_name(ref_tree, PT.get_name(zone), depth=2)
    for node_name in ["ZoneBC", "ZoneGridConnectivity"]:
      assert PT.is_same_tree(PT.get_child_from_name(zone, node_name), PT.get_child_from_name(ref_zone, node_name))

  if write_output:
    out_dir = MU.test_utils.create_pytest_output_dir(comm)
    MIO.dist_tree_to_file(dist_treeU, os.path.join(out_dir, 'tree_U.hdf'), comm)

@pytest_parallel.mark.parallel(2)
def test_s2u_hybrid(comm, write_output):
  mesh_file = os.path.join(MU.test_utils.mesh_dir, 'H_elt_and_s.yaml')
  dist_tree = MIO.file_to_dist_tree(mesh_file, comm)

  dist_tree_u = convert_s_to_ngon(dist_tree, comm)

  for zone in PT.iter_all_Zone_t(dist_tree_u):
    assert PT.Zone.Type(zone) == 'Unstructured'
    for pl in PT.iter_nodes_from_label(zone, 'IndexArray_t'):
      assert PT.get_value(pl).shape[0] == 1 #All PLs should be (1,N)

  if write_output:
    out_dir = MU.test_utils.create_pytest_output_dir(comm)
    MIO.dist_tree_to_file(dist_tree_u, os.path.join(out_dir, 'tree_U.hdf'), comm)

@pytest_parallel.mark.parallel([1])
def test_s2u_withdata(comm, write_output):
  mesh_file = os.path.join(MU.test_utils.mesh_dir,  'S_twoblocks.yaml')

  dist_treeS = MIO.file_to_dist_tree(mesh_file, comm)

  # Use only small zone for simplicity
  PT.rm_nodes_from_name(dist_treeS, 'Large')
  PT.rm_nodes_from_label(dist_treeS, 'ZoneGridConnectivity_t')

  # Add some BCDataFace data
  bc_right = PT.yaml.parse_yaml_cgns.to_node(
    """
    Right BC_t 'BCInflow':
      PointRange IndexRange_t I4 [[1, 6], [1, 1], [1, 4]]:
      GridLocation GridLocation_t 'JFaceCenter':
      WholeDSFace BCDataSet_t "Null":
        NeumannData BCData_t:
          lid DataArray_t I4 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]:
      SubDSFace BCDataSet_t "Null":
        GridLocation GridLocation_t "JFaceCenter":
        PointRange IndexRange_t I4 [[1,2], [1,1], [1,4]]:
        DirichletData BCData_t:
          lid DataArray_t I4 [1,2,3,4,5,6,7,8]:
      SubDSVtx BCDataSet_t "Null":
        GridLocation GridLocation_t "Vertex":
        PointRange IndexRange_t I4 [[1, 2], [1, 1], [1, 5]]:
        DirichletData BCData_t:
          lid DataArray_t I4 [1,2,3,4,5,6,7,8,9,10]:
    """)
  PT.rm_nodes_from_name(dist_treeS, 'Right')
  PT.add_child(PT.get_node_from_label(dist_treeS, 'ZoneBC_t'), \
      MF.full_to_dist.distribute_pl_node(bc_right, comm))

  dist_treeU = convert_s_to_ngon(dist_treeS, comm)

  # Some checks
  bc_right_u = PT.get_node_from_name(dist_treeU, 'Right')
  assert PT.get_node_from_path(bc_right_u, 'WholeDSFace/GridLocation') is None
  assert PT.Subset.GridLocation(PT.get_node_from_name(bc_right_u, 'SubDSFace')) == 'FaceCenter'
  assert PT.Subset.GridLocation(PT.get_node_from_name(bc_right_u, 'SubDSVtx')) == 'Vertex'
  assert PT.get_node_from_path(bc_right_u, 'WholeDSFace/PointList') is None
  assert (PT.get_node_from_path(bc_right_u, 'SubDSFace/PointList')[1] == [225,226,279,280,333,334,387,388]).all()
  assert (PT.get_node_from_path(bc_right_u, 'SubDSVtx/PointList')[1] == [1,2,64,65,127,128,190,191,253,254]).all()
  for bcds in PT.get_children_from_label(bc_right_u, 'BCDataSet_t'): #Data should be the same
    bcds_s = PT.get_node_from_name(bc_right, PT.get_name(bcds))
    assert (PT.get_node_from_name(bcds, 'lid')[1] == PT.get_node_from_name(bcds_s, 'lid')[1]).all()

  if write_output:
    out_dir = MU.test_utils.create_pytest_output_dir(comm)
    MIO.dist_tree_to_file(dist_treeU, os.path.join(out_dir, 'tree_U.hdf'), comm)


#!/usr/bin/env python3
from Bio import SeqIO
from Bio import AlignIO
from utils import *

sars = SeqIO.read("Sars_CoV_2","fasta") # get unaligned sars
sars_align = AlignIO.read("data/alignment","fasta")._records[0] # get aligned sars
proteome = get_proteome("proteome.csv") # get unaligned proteome

mapping = [0]*len(sars_align) # init container for mapping
j = 1
for i,nucl in enumerate(sars_align): # for each nucleotide in aligned sars
    if(nucl=="-"): # if indel
        mapping[i] = -1 # don't map
    else: # if not
        mapping[i] = j # map
        j += 1 # iterate
for protein in proteome: # for each protein in unaligned proteome
    start = proteome[protein]["Start"] # get start for this protein
    stop = proteome[protein]["Stop"] # get stop for this protein
    proteome[protein]["Start"] = mapping.index(start)
    proteome[protein]["Stop"] = mapping.index(stop)

file = open("askd.csv","w")
file.write("#Name,Start,Stop")
for protein in proteome:
    file.write(protein+","+str(proteome[protein]["Start"]+1)+","+str(proteome[protein]["Stop"]+1)+"\n")

file.close()


import json

with open('dict.json') as json_data:
    data = json.load(json_data)

    mDate = '040117' #set this manually for now
    i = 0

    for term in data['terms']:
	    i += 1
	    term['uniqueID'] = mDate + 'n' + str(i)
	    print(term)

    with open('outputFile.json', 'w') as outfile:
	    json.dump(data, outfile)


# -*- coding: UTF-8 -*-
"""
TUI module test cases
@author: Aurélien Gâteau <mail@agateau.com>
@license: GPL v3 or later
"""

import os
import unittest

from yokadi.ycli import tui

class TuiTestCase(unittest.TestCase):
    def setUp(self):
        tui.clearInputAnswers()

    def testEditEmptyText(self):
        os.environ["EDITOR"] = "/bin/true"
        out = tui.editText(None)
        self.assertEqual(out, "")

    def testEnterInt(self):
        tui.addInputAnswers("")
        self.assertEqual(tui.enterInt(), None)

        tui.addInputAnswers("a", "12")
        self.assertEqual(tui.enterInt(default=4), 12)

    def testSelectFromList(self):
        lst = [("a", "alpha"), ("b", "bravo"), ("c", "charlie")]
        tui.addInputAnswers("a")
        value = tui.selectFromList(lst, valueForString=str)
        self.assertEqual(value, "a")

        tui.addInputAnswers("z", "b")
        value = tui.selectFromList(lst, valueForString=str)
        self.assertEqual(value, "b")

    def testConfirm(self):
        tui.addInputAnswers("zog", "y")
        value = tui.confirm("bla")
        self.assertTrue(value)

        tui.addInputAnswers("zog", "n")
        value = tui.confirm("bla")
        self.assertFalse(value)


"""
File: non_max_suppression.py
Author: Shaurya Chandhoke
Description: Helper file which contains the functions used for Non-Maximum Suppression
"""
import numpy as np

def imagePolish(image, threshold):
    """
    Final polish up of the image after Non-Maximum Suppression has been applied. This will convert the image to an
    unsigned 8 bit integer which will allow for display and saving.

    :param image: The pre-processed image as a 2D numpy array.
    :param threshold: The lower bound value to re-apply to the image. This is due to changing from float back to uint8.
    :return: The finalized image
    """
    scale_min = np.min(image)
    scale_max = np.max(image)

    image = np.uint8((image - scale_min) / (scale_max - scale_min) * 255)
    image = np.where(image > threshold, 255, 0)
    image = np.uint8(image)

    return image

def roundNearestDegree(deg):
    """
    A function that will round a degree value to one of 8 values respective to their sub quadrants in the unit circle.

    Because this function will be called multiple times in quick succession for each element in the Gradient Angle
    matrix, this function will be first vectorized prior to calling to allow for greater performance.

    To assign the degree value to its respective rounded quadrant angle, the following comparisons will be used:
        In total, the degree passed will round to 1 of 8 possible values:
            * 0 (also synonymous with 360)
            * 45
            * 90
            * 135
            * 180
            * 225
            * 270
            * 315

    :param deg: Element wise degree value passed from the Gradient Angle matrix
    :return: A rounded degree value based on the 8 sub quadrants of the unit circle
    """
    if (0 <= deg <= 22) or (338 <= deg <= 360):
        return 0
    elif 23 <= deg <= 67:
        return 45
    elif 68 <= deg <= 112:
        return 90
    elif 113 <= deg <= 157:
        return 135
    elif 158 <= deg <= 202:
        return 180
    elif 203 <= deg <= 247:
        return 225
    elif 248 <= deg <= 292:
        return 270
    elif 293 <= deg <= 337:
        return 315

def nonMaxSuppression(gradientMagnitudes, gradientAngles, threshold):
    """
    A helper function to perform Non-Maximum suppression. This function will first round the Gradient Angles matrix,
    then determine which pixels to compare based on the rounded values. It will perform the following comparisons:

        * If the angle is vertical (90 or 270), it means the edge is horizontal and will check pixels above and below
        * If the angle is horizontal (0 or 180), it means the edge is vertical and will check pixels left and right
        * If the angle is a Quadrant I or III angle (45 or 225), it means the edge is diagonal and will check pixels
          in those Quadrants
        * If the angle is a Quadrant II or IV angle (135 or 315), it means the edge is diagonal and will check pixels
          in those Quadrants

    :param gradientMagnitudes: A 2D numpy array of the image after the Sobel filter is applied
    :param gradientAngles: A 2D numpy array containing the direction of the Gradient after the Sobel filter is applied.
    :param threshold: An 8 bit [0-255] threshold value to clean the image after performing Non-Maximum Suppression.
    :return: The finalized image as a 2D numpy array
    """
    scaledAngles = np.int16(gradientAngles)
    bufferImage = np.zeros(shape=gradientMagnitudes.shape, dtype=gradientMagnitudes.dtype)

    # Vectorizing the function increases its efficiency
    degreeRounder = np.vectorize(roundNearestDegree)
    scaledAngles = degreeRounder(scaledAngles)

    # Creating a 1 pixel wide buffer zone across the input image to allow for diagonal pixel checking
    for i in range(1, len(scaledAngles) - 1):
        for j in range(1, len(scaledAngles[i]) - 1):
            magnitude = gradientMagnitudes[i, j]
            theta = scaledAngles[i, j]

            # Horizontal edge -- check above and below
            if theta == 90 or theta == 270:
                above = gradientMagnitudes[i - 1, j]
                below = gradientMagnitudes[i + 1, j]
                if magnitude > above and magnitude > below:
                    bufferImage[i, j] = magnitude
                else:
                    bufferImage[i, j] = 0

            # Vertical edge -- check left and right
            elif theta == 0 or theta == 180:
                left = gradientMagnitudes[i, j - 1]
                right = gradientMagnitudes[i, j + 1]

                if magnitude > left and magnitude > right:
                    bufferImage[i, j] = magnitude
                else:
                    bufferImage[i, j] = 0

            # Quadrant I and Quadrant III edge -- check both diagonal orientations
            elif theta == 45 or theta == 225:
                upperDiagonal = gradientMagnitudes[i - 1, j - 1]
                lowerDiagonal = gradientMagnitudes[i + 1, j + 1]

                if magnitude > upperDiagonal and magnitude > lowerDiagonal:
                    bufferImage[i, j] = magnitude
                else:
                    bufferImage[i, j] = 0

            # Quadrant II and Quadrant IV edge -- check both diagonal orientations
            elif theta == 135 or theta == 315:
                upperDiagonal = gradientMagnitudes[i - 1, j + 1]
                lowerDiagonal = gradientMagnitudes[i + 1, j - 1]

                if magnitude > upperDiagonal and magnitude > lowerDiagonal:
                    bufferImage[i, j] = magnitude
                else:
                    bufferImage[i, j] = 0

    finalizedImage = imagePolish(bufferImage, threshold)
    return finalizedImage


import sys
import cv2 as cv
import numpy as np
import os
import math
import constants

# https://docs.opencv.org/3.4/d4/d70/tutorial_hough_circle.html
def makeCircles(src):
    # gray = cv.medianBlur(src, 17)
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

    col = gray.shape[1]
    gray = cv.GaussianBlur(gray, (5, 5), 1.5)

    circles = cv.HoughCircles(
        gray,
        cv.HOUGH_GRADIENT,
        1.2,
        col // 18,
        param1=100,
        param2=50,
        minRadius=col // 50,
        maxRadius=col // 5,
    )

    return None if circles is None else circles[0, :]

def findPointsOnCircle(x, y, rad, n, maxX, maxY):
    t = 0
    result = []
    step = math.pi * 2 / n
    rad *= 1.1

    while t < math.pi * 2:
        dx = math.cos(t) * rad
        dy = math.sin(t) * rad
        xlist = [0, x + dx, maxX]
        ylist = [0, y + dy, maxY]
        xlist.sort()
        ylist.sort()
        result.append((int(xlist[1]), int(ylist[1])))
        t += step

    return result

def openFile(filename, directory):
    f = os.path.join(directory, filename)
    src = None
    if os.path.isfile(f):
        src = cv.imread(cv.samples.findFile(f), cv.IMREAD_COLOR)
    if src is None:
        print("Error opening image!")
        print("Usage: hough_circle.py [image_name -- default " + f + "] \n")
        return -1
    return src

def labelCircle(img):
    cv.imshow(constants.DISPLAY_WINDOW_NAME, img)
    print(
        "Classify image: [0='1', 1='10', 2='100', 3='5', 4='50', 5='500', enter=<skip>]"
    )
    # c = int(input())
    key = cv.waitKey(0)
    label = -1
    while key != 13:
        classes = [1, 10, 100, 5, 50, 500]
        label = classes[key - 48]
        print("Selected: %s" % (label))
        print("Press <enter> to finalize")
        key = cv.waitKey(0)
        print()
    return label

def cleanCircles(circles):
    i = 0
    while i < len(circles):
        current = circles[i]
        j = i + 1

        while j < len(circles):
            other = circles[j]

            dx = int(other[0]) - current[0]
            dy = int(other[1]) - current[1]
            distance = pow(dx, 2) + pow(dy, 2)
            if distance < pow(
                max(other[2], current[2]), 2
            ) * constants.OVERLAP_THREASHOLD and other[2] in range(
                int(current[2] * 0.7), int(current[2] * 1.3)
            ):
                if current[2] < other[2]:
                    circles = np.delete(circles, i, 0)
                    i -= 1
                    break
                else:
                    circles = np.delete(circles, j, 0)
                    j -= 1
            j += 1
        i += 1
    return circles

def findCircles():
    if not os.path.exists(constants.LABEL_DIRECTORY):
        os.mkdir(constants.LABEL_DIRECTORY)
    if not os.path.exists(constants.LABELED_IMAGES_DIRECTORY):
        os.mkdir(constants.LABELED_IMAGES_DIRECTORY)

    directory = constants.COMPRESS_DIRECTORY
    for filename in os.listdir(directory):
        # original = openFile(filename, constants.TRAINING_DATA_DIRECTORY)
        # cv.imshow("original", original)
        # cv.waitKey(0)
        src = openFile(filename, directory)
        final = src.copy()

        rows = src.shape[1]
        cols = src.shape[0]

        circles = makeCircles(src)
        if circles is None:
            continue

        circles = np.uint16(np.around(circles))
        # circles = cleanCircles(circles)

        imageLabel = []
        for i in circles:
            print(i)
            imgCopy = src.copy()
            center = (i[0], i[1])
            cv.circle(imgCopy, center, 1, (0, 100, 100), 3)
            cv.circle(final, center, 1, (0, 100, 100), 3)

            # circle points
            points = findPointsOnCircle(
                i[0], i[1], i[2], 12, imgCopy.shape[1], imgCopy.shape[0]
            )
            for p in points:
                cv.circle(imgCopy, p, 1, (255, 0, 255), 3)
                cv.circle(final, p, 1, (255, 0, 255), 3)

            label = labelCircle(imgCopy)

            if not label == -1:
                circleLabel = (
                    str(label)
                    + " "
                    + " ".join(
                        [str(p[0] / rows) + " " + str(p[1] / cols) for p in points]
                    )
                )

                imageLabel.append(circleLabel)

        data = "\n".join(imageLabel)

        labelfilename = constants.LABEL_DIRECTORY + "/" + filename[:-4] + ".txt"
        f = open(labelfilename, "w")
        f.write(data)
        f.close()

        cv.imwrite(
            constants.LABELED_IMAGES_DIRECTORY + "/transformed" + filename, final
        )

    return 0


class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        '''
        1. if we encounter 0 => set matrix[0][y] = 0 and matrix[x][0] = 0
        2. looking for x=0 and y=0 to set its enitre row and column to 0's
        '''
        height = len(matrix)
        width = len(matrix[0])

        # mark first row and column
        if matrix[0][0] == 0:
            mark_x_0 = mark_0_y = True
        else:
            mark_x_0 = mark_0_y = False

        for i in range(1, height):
            if matrix[i][0] == 0:
                mark_x_0 = True

        for j in range(1, width):
            if matrix[0][j] == 0:
                mark_0_y = True

        # mark 0
        for i in range(1, height):
            for j in range(1, width):
                if matrix[i][j] == 0:
                    matrix[i][0] = 0
                    matrix[0][j] = 0

        # replace 0
        for i in range(1, height):
            if matrix[i][0] == 0:
                for j in range(1, width):
                    matrix[i][j] = 0

        for j in range(1, width):
            if matrix[0][j] == 0:
                for i in range(1, height):
                    matrix[i][j] = 0

        # replace first row and column
        if mark_x_0:
            for i in range(height):
                matrix[i][0] = 0
        if mark_0_y:
            for j in range(width):
                matrix[0][j] = 0


import requests
import json
from bs4 import BeautifulSoup
import datetime as dt
import time
from os import rename

#event_url = "imagine-dragons-evolve-world-tour/floor/c935b272-3019-48b9-877e-77f7f95b9a61/510954"
#url = "https://www.ticketswap.nl/event/"+event_url

def get_event_stats(url):
    page = requests.get(url)
    soup = BeautifulSoup(page.text, 'lxml')
    available = -1
    sold = -1
    wanted = -1
    try:
        available = soup.find("div", {'class' : 'counter counter-available'}).find("div", {'class' : 'counter-value'}).text
        sold = soup.find("div", {'class' : 'counter counter-sold'}).find("div", {'class' : 'counter-value'}).text
        wanted = soup.find("div", {'class' : 'counter counter-wanted'}).find("div", {'class' : 'counter-value'}).text
    except:
        name = url[31:]
        name = name[:name.index("/")].split("-")
        print(name)
    return [int(available), int(sold), int(wanted)]

def get_event_title(url):
    page = requests.get(url)
    soup = BeautifulSoup(page.text, 'lxml')

    return soup.find("h1", {'itemprop' : 'summary'}).find("a").text

def get_event_date(url):
    page = requests.get(url)
    soup = BeautifulSoup(page.text, 'lxml')

    monthdict = {'januari' : '1', 'februari' : '2', 'maart' : '3', 'april' : '4', 'mei' : '5', 'juni' : '6', 'juli' : '7', 'augustus' : '8', 'september' : '9', 'oktober' : '10', 'november' : '11', 'december' : '12',}

    date = soup.find("span", {'class' : 'date'}).text[1:]

    try:
        date = date[:date.index("-")-1]
    except:
        pass

    date = date[date.index(" ")+1:]
    day = date[:date.index(" ")]
    month = monthdict[date[date.index(" ")+1:-5]]
    year = date[-4:]

    event_date = dt.datetime(int(year), int(month), int(day), 21)
    t = dt.datetime.today()
    today = dt.datetime(t.year, t.month, t.day, t.hour)

    event_timestamp = time.mktime(event_date.timetuple())
    return event_timestamp

def get_date_diff(event_timestamp):
    today_timestamp = int(time.time())

    diff_s = event_timestamp - today_timestamp
    diff_h = int(diff_s/3600.0)

    return diff_h