import re
from dataclasses import dataclass, field, fields
from typing import Optional

from omegaconf import II

from espresso.models.transformer.speech_transformer_config import SpeechEncoderConfig
from fairseq import utils
from fairseq.dataclass import ChoiceEnum, FairseqDataclass
from fairseq.models.transformer.transformer_config import (
    DEFAULT_MIN_PARAMS_TO_WRAP,
    QuantNoiseConfig,
    TransformerConfig,
)
from fairseq.utils import safe_getattr, safe_hasattr

DEFAULT_MAX_SOURCE_POSITIONS = 10240
DEFAULT_MAX_TARGET_POSITIONS = 1024

_NAME_PARSER = r"(decoder|encoder|quant_noise)_(.*)"

@dataclass
class SpeechDecoderConfig(FairseqDataclass):
    embed_path: Optional[str] = field(
        default=None, metadata={"help": "path to pre-trained decoder embedding"}
    )
    embed_dim: int = field(default=48, metadata={"help": "decoder embedding dimension"})
    hidden_size: int = field(default=320, metadata={"help": "decoder hidden size"})
    layers: int = field(default=3, metadata={"help": "num decoder layers"})
    residual: bool = field(
        default=False,
        metadata={
            "help": "create residual connections for rnn decoder "
            "layers (starting from the 2nd layer), i.e., the actual "
            "output of such layer is the sum of its input and output"
        },
    )
    dropout_in: Optional[float] = field(
        default=II("model.dropout"),
        metadata={"help": "dropout probability for decoder input embedding"},
    )
    dropout_out: Optional[float] = field(
        default=II("model.dropout"),
        metadata={"help": "dropout probability for decoder output"},
    )

@dataclass
class SpeechTransformerTransducerConfig(FairseqDataclass):
    activation_fn: ChoiceEnum(utils.get_available_activation_fns()) = field(
        default="relu",
        metadata={"help": "activation function to use"},
    )
    dropout: float = field(default=0.1, metadata={"help": "dropout probability"})
    attention_dropout: float = field(
        default=0.0, metadata={"help": "dropout probability for attention weights"}
    )
    activation_dropout: float = field(
        default=0.0,
        metadata={
            "help": "dropout probability after activation in FFN.",
            "alias": "--relu-dropout",
        },
    )
    adaptive_input: bool = field(
        default=False,
        metadata={"help": "if set, uses adaptive input"},
    )
    encoder: SpeechEncoderConfig = SpeechEncoderConfig()
    decoder: SpeechDecoderConfig = SpeechDecoderConfig()
    joint_dim: int = field(
        default=512, metadata={"help": "joint network output dimension"}
    )
    share_decoder_input_output_embed: bool = field(
        default=False, metadata={"help": "share decoder input and output embeddings"}
    )
    no_token_positional_embeddings: bool = field(
        default=False,
        metadata={
            "help": "if True, disables positional embeddings (outside self attention)"
        },
    )
    layernorm_embedding: bool = field(
        default=True, metadata={"help": "add layernorm to embedding"}
    )
    no_scale_embedding: bool = field(
        default=False, metadata={"help": "if True, dont scale embeddings"}
    )
    checkpoint_activations: bool = field(
        default=False,
        metadata={
            "help": "checkpoint activations at each layer, which saves GPU memory usage at the cost of some additional compute"
        },
    )
    offload_activations: bool = field(
        default=False,
        metadata={
            "help": "checkpoint activations at each layer, then save to gpu. Sets --checkpoint-activations."
        },
    )
    # args for Training with Quantization Noise for Extreme Model Compression ({Fan*, Stock*} et al., 2020)
    quant_noise: QuantNoiseConfig = field(default=QuantNoiseConfig())
    min_params_to_wrap: int = field(
        default=DEFAULT_MIN_PARAMS_TO_WRAP,
        metadata={
            "help": "minimum number of params for a layer to be wrapped with FSDP() when "
            "training with --ddp-backend=fully_sharded. Smaller values will "
            "improve memory efficiency, but may make torch.distributed "
            "communication less efficient due to smaller input sizes. This option "
            "is set to 0 (i.e., always wrap) when --checkpoint-activations or "
            "--offload-activations are passed."
        },
    )
    # DEPRECATED field, but some old checkpoints might have it
    relu_dropout: float = 0.0

    export: bool = field(
        default=False,
        metadata={"help": "make the layernorm exportable with torchscript."},
    )

    # options from other parts of the config
    max_source_positions: Optional[int] = II("task.max_source_positions")
    max_target_positions: Optional[int] = II("task.max_target_positions")
    tpu: bool = II("common.tpu")

    # We need to make this hierarchical dataclass like the flat namespace
    # __getattr__ and __setattr__ here allow backward compatibility
    # for subclasses of Transformer(Legacy) that depend on read/write on
    # the flat namespace.

    def __getattr__(self, name):
        match = re.match(_NAME_PARSER, name)
        if match:
            sub = safe_getattr(self, match[1])
            return safe_getattr(sub, match[2])
        raise AttributeError(f"invalid argument {name}.")

    def __setattr__(self, name, value):
        match = re.match(_NAME_PARSER, name)
        if match:
            sub = safe_getattr(self, match[1])
            setattr(sub, match[2], value)
        else:
            super().__setattr__(name, value)

    @staticmethod
    def _copy_keys(args, cls, prefix, seen):
        return TransformerConfig._copy_keys(args, cls, prefix, seen)

    @classmethod
    def from_namespace(cls, args):
        if args is None:
            return None
        if not isinstance(args, cls):
            seen = set()
            config = cls()
            # currently, we can go generically from DC fields to args hierarchically
            # but we can't easily deconstruct a flat namespace to a hierarchical
            # DC. Mostly because we could have a sub-dc called `decoder-foo` that should not
            # go to the sub struct called `decoder`. There are ways to go around this, but let's keep it simple
            # for now.
            for fld in fields(cls):
                # concretelly, the transformer_config know what sub-dc it has, so we go through all the dc fields
                # and if it's one that has a sub-dc, we build that sub-dc with `copy_keys()`
                if fld.name == "decoder":
                    if safe_hasattr(args, "decoder"):
                        #  in some cases, the args we receive is already structured (as DictConfigs), so let's just build the correct DC
                        seen.add("decoder")
                        config.decoder = SpeechDecoderConfig(**args.decoder)
                    else:
                        config.decoder = cls._copy_keys(
                            args, SpeechDecoderConfig, "decoder", seen
                        )
                elif fld.name == "encoder":
                    # same but for encoder
                    if safe_hasattr(args, "encoder"):
                        seen.add("encoder")
                        config.encoder = SpeechEncoderConfig(**args.encoder)
                    else:
                        config.encoder = cls._copy_keys(
                            args, SpeechEncoderConfig, "encoder", seen
                        )
                elif fld.name == "quant_noise":
                    # same but for quant_noise
                    if safe_hasattr(args, "quant_noise"):
                        seen.add("quant_noise")
                        config.quant_noise = QuantNoiseConfig(**args.quant_noise)
                    else:
                        config.quant_noise = cls._copy_keys(
                            args, QuantNoiseConfig, "quant_noise", seen
                        )
                elif safe_hasattr(args, fld.name):
                    # if it's not a structure field, it's just a normal field, copy it over
                    seen.add(fld.name)
                    setattr(config, fld.name, safe_getattr(args, fld.name))
            # we got all the fields defined in the dataclass, but
            # the argparse namespace might have extra args for two reasons:
            #   - we are in a legacy class so all the args are not declared in the dataclass. Ideally once everyone has defined a dataclass for their model, we won't need this
            #   - some places expect args to be there but never define them
            args_dict = (
                args._asdict()
                if safe_hasattr(args, "_asdict")
                else vars(args)
                if safe_hasattr(args, "__dict__")
                else {}
            )  # namedtupled doesn't have __dict__ :-/
            for key, value in args_dict.items():
                if key not in seen:
                    setattr(config, key, value)
            return config
        else:
            return args


import argparse
import pathlib
import shutil
import subprocess

SCRIPT_DIR = pathlib.Path(__file__).parent.resolve()
DEFAULT_OPS_CONFIG_RELATIVE_PATH = "tools/ci_build/github/android/mobile_package.required_operators.config"
DEFAULT_BUILD_SETTINGS_RELATIVE_PATH = "tools/ci_build/github/android/default_mobile_aar_build_settings.json"

def parse_args():
    parser = argparse.ArgumentParser(
        description="""Builds a custom ONNX Runtime Android package.
                    This script first builds a Docker image with the ONNX Runtime Android build environment
                    dependencies. Then, from a Docker container with that image, it calls the ONNX Runtime build
                    scripts to build a custom Android package. The resulting package will be under
                    <working_dir>/output/aar_out. See https://onnxruntime.ai/docs/build/custom.html for more
                    information about custom builds."""
    )

    parser.add_argument(
        "working_dir", type=pathlib.Path, help="The directory used to store intermediate and output files."
    )

    parser.add_argument(
        "--onnxruntime_branch_or_tag",
        help="The ONNX Runtime branch or tag to build. "
        "Supports branches and tags starting from 1.11 (branch rel-1.11.0 or tag v1.11.0). "
        "If unspecified, builds the latest.",
    )

    parser.add_argument(
        "--onnxruntime_repo_url", help="The ONNX Runtime repo URL. If unspecified, uses the official repo."
    )

    parser.add_argument(
        "--include_ops_by_config",
        type=pathlib.Path,
        help="The configuration file specifying which ops to include. "
        "Such a configuration file is generated during ONNX to ORT format model conversion. "
        f"The default is {DEFAULT_OPS_CONFIG_RELATIVE_PATH} in the ONNX Runtime repo.",
    )

    parser.add_argument(
        "--build_settings",
        type=pathlib.Path,
        help="The configuration file specifying the build.py options. "
        f"The default is {DEFAULT_BUILD_SETTINGS_RELATIVE_PATH} in the ONNX Runtime repo.",
    )

    default_config = "Release"
    parser.add_argument(
        "--config",
        choices=["Debug", "MinSizeRel", "Release", "RelWithDebInfo"],
        default=default_config,
        help="The build configuration. " f"The default is {default_config}.",
    )

    default_docker_image_tag = "onnxruntime-android-custom-build:latest"
    parser.add_argument(
        "--docker_image_tag",
        default=default_docker_image_tag,
        help="The tag for the Docker image. " f"The default is {default_docker_image_tag}.",
    )

    parser.add_argument(
        "--docker_path",
        default=shutil.which("docker"),
        help="The path to docker. If unspecified, docker should be in PATH.",
    )

    args = parser.parse_args()

    if args.docker_path is None:
        raise ValueError("Unable to determine docker path. Please provide it with --docker_path.")

    return args

def main():
    args = parse_args()

    docker_build_args = []
    if args.onnxruntime_branch_or_tag:
        docker_build_args += ["--build-arg", f"ONNXRUNTIME_BRANCH_OR_TAG={args.onnxruntime_branch_or_tag}"]
    if args.onnxruntime_repo_url:
        docker_build_args += ["--build-arg", f"ONNXRUNTIME_REPO={args.onnxruntime_repo_url}"]

    docker_build_cmd = (
        [
            args.docker_path,
            "build",
            "--tag",
            args.docker_image_tag,
            "--file",
            str(SCRIPT_DIR / "Dockerfile"),
        ]
        + docker_build_args
        + [str(SCRIPT_DIR)]
    )

    subprocess.run(docker_build_cmd, check=True)

    working_dir = args.working_dir
    working_dir.mkdir(parents=True, exist_ok=True)
    working_dir = working_dir.resolve()

    # copy over any custom build configuration files
    config_files = [f for f in [args.include_ops_by_config, args.build_settings] if f]
    if config_files:
        input_dir = working_dir / "input"
        input_dir.mkdir(exist_ok=True)
        for config_file in config_files:
            shutil.copy(config_file, input_dir)

    output_dir = working_dir / "output"
    output_dir.mkdir(exist_ok=True)

    container_ops_config_file = (
        f"/workspace/shared/input/{args.include_ops_by_config.name}"
        if args.include_ops_by_config
        else f"/workspace/onnxruntime/{DEFAULT_OPS_CONFIG_RELATIVE_PATH}"
    )

    container_build_settings_file = (
        f"/workspace/shared/input/{args.build_settings.name}"
        if args.build_settings
        else f"/workspace/onnxruntime/{DEFAULT_BUILD_SETTINGS_RELATIVE_PATH}"
    )

    docker_run_cmd = [
        args.docker_path,
        "run",
        "--rm",
        "-it",
        f"--volume={str(working_dir)}:/workspace/shared",
        args.docker_image_tag,
        "/usr/bin/env",
        "python3",
        "/workspace/onnxruntime/tools/ci_build/github/android/build_aar_package.py",
        "--build_dir=/workspace/shared/output",
        f"--config={args.config}",
        f"--include_ops_by_config={container_ops_config_file}",
        container_build_settings_file,
    ]

    subprocess.run(docker_run_cmd, check=True)

    print("Finished building Android package at '{}'.".format(output_dir / "aar_out"))

if __name__ == "__main__":
    main()


__author__ = 'Lionel Cacheux'
__date__ = '2018-07-19'
__copyright__ = '(C) 2018 by Lionel Cacheux'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import sys
import inspect
import os.path
from os import path
import shutil

from qgis.core import QgsProcessingAlgorithm, QgsApplication, QgsStyle, Qgis, QgsSettings

from qgis.PyQt.QtWidgets import *

from .ThematicProvider import ThematicProvider
from qgis.utils import iface
from PyQt5.QtGui import QIcon
from qgis.PyQt.QtCore import QSettings

from .palette_dialog import AddPaletteDialog
from .remove_palette_dialog import RemovePaletteDialog

cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0]

if cmd_folder not in sys.path:
    sys.path.insert(0, cmd_folder)

class ThematicPlugin(object):

    def __init__(self):
        # self.provider = ThematicProvider()
        # remplacé par
        self.provider =  None

    def initProcessing(self):
        """Init Processing provider for QGIS >= 3.8."""
        self.provider = ThematicProvider()
        QgsApplication.processingRegistry().addProvider(self.provider)

    def initGui(self):
        # Ajout
        """Init Processing provider for QGIS >= 3.8."""

        self.initProcessing()

        try:

            if 'INSEE' in os.getenv('USERDNSDOMAIN'):

                pluginPath = os.path.abspath(os.path.dirname(__file__))
                images = pluginPath + os.sep + "images" + os.sep
                self.pluginMenu = iface.settingsMenu().addMenu(QIcon(images + 'palette_2018.svg'), "Palette Insee 2018")

                self.actionAdd = QAction(QIcon(images + 'palette_2018.svg'),
                                          "Installer la palette", iface.mainWindow())
                self.actionAdd.triggered.connect(self.runAddPalette)
                self.first_start_actionAdd = True

                self.actionRemove = QAction(QIcon(images + 'palette_2018_remove.svg'),
                                          "Supprimer l'ancienne palette", iface.mainWindow())
                self.actionRemove.triggered.connect(self.runRemovePalette)
                self.first_start_actionRemove = True

                # self.actionAide.triggered.connect(showHelp)
                self.pluginMenu.addAction(self.actionAdd)
                self.pluginMenu.addAction(self.actionRemove)
        except:
            pass

        else:
            pass

    def unload(self):
        QgsApplication.processingRegistry().removeProvider(self.provider)

        # if hasattr(self, 'actionEditor'):  iface.removeToolBarIcon(self.actionEditor)
        try:
            self.pluginMenu.parentWidget().removeAction(self.pluginMenu.menuAction())  # Remove from Extension menu
            QgsApplication.processingRegistry().removeProvider(self.provider)
        except:
            pass

    def runAddPalette(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start_actionAdd == True:
            self.first_start_actionAdd = False
            self.dlgAdd = AddPaletteDialog()

        # show the dialog
        self.dlgAdd.show()
        # Run the dialog event loop
        result = self.dlgAdd.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            qstyles = QgsStyle.defaultStyle()

            favoriteRamps = qstyles.symbolsOfFavorite(QgsStyle.StyleEntity.ColorrampEntity)
            for i in favoriteRamps:
                qstyles.removeFavorite(QgsStyle.StyleEntity.ColorrampEntity, i)

            qstyles.importXml(os.path.abspath(os.path.dirname(__file__)) + '/palettes/symbology-style.xml')

            listeGpl = os.listdir(os.path.abspath(os.path.dirname(__file__)) + '/palettes')
            for item in listeGpl:
                fichier = os.path.abspath(os.path.dirname(__file__)) + '/palettes/' + item
                shutil.copy(fichier, re.sub('\\\\', '/', QgsApplication.qgisSettingsDirPath()) + '/palettes')

                QgsApplication.qgisSettingsDirPath()

            newFavorites = ['Insee-Bleu_2P', 'Insee-Bleu_3P', 'Insee-Bleu_4P', 'Insee-Bleu_5P', 'Insee-Bleu_6P', 'Insee-Jaune_1N1P', 'Insee-Jaune_1N2P', 'Insee-Jaune_1N3P', 'Insee-Jaune_1N4P', 'Insee-Jaune_1N5P', 'Insee-Jaune_2N1P', 'Insee-Jaune_2N2P', 'Insee-Jaune_2N3P', 'Insee-Jaune_2N4P', 'Insee-Jaune_3N1P', 'Insee-Jaune_3N2P', 'Insee-Jaune_3N3P', 'Insee-Jaune_4N1P', 'Insee-Jaune_4N2P', 'Insee-Jaune_5N1P']
            for i in newFavorites:
                qstyles.addFavorite(QgsStyle.StyleEntity.ColorrampEntity,i)

            app = QgsApplication.instance()

            params = QgsSettings(
                app.qgisSettingsDirPath() + "QGIS/QGIS3.ini", QSettings.IniFormat
            )

            params.setValue('colors/showInMenuList', ['Insee2018 - Couleurs de base','Insee2018 Bleu—Jaune'])
            for item in QgsApplication.colorSchemeRegistry().schemes():
                QgsApplication.colorSchemeRegistry().removeColorScheme(item)

            # QgsApplication.colorSchemeRegistry().addUserSchemes()
            QgsApplication.colorSchemeRegistry().addDefaultSchemes()

            iface.messageBar().pushMessage("Palette", "La palette de couleurs Insee a été installée", level=Qgis.Info)

    def runRemovePalette(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start_actionRemove == True:
            self.first_start_actionRemove = False
            self.dlgRemove = RemovePaletteDialog()

        # show the dialog
        self.dlgRemove.show()
        # Run the dialog event loop
        result = self.dlgRemove.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            style = QgsStyle.defaultStyle()

            listeTagsSymbols = ['Contours', 'Analyses', 'Dossier', 'Flash', 'IP', 'Insee']
            # listeIdTagsSymbols = [style.tagId(n) for n in listeTagsSymbols]
            for symbolIdTag in [style.tagId(n) for n in listeTagsSymbols]:
                for i in style.symbolsWithTag(QgsStyle.StyleEntity.SymbolEntity, symbolIdTag):
                    style.removeSymbol(i)

            listeTagsRamps = ['Analyses_deg', 'Dossier_deg', 'Flash_deg', 'IP_deg']
            # listeIdTagsRamps = [style.tagId(n) for n in listeTagsRamps]
            for rampIdTag in [style.tagId(n) for n in listeTagsRamps]:
                for i in style.symbolsWithTag(QgsStyle.StyleEntity.ColorrampEntity, rampIdTag):
                    style.removeColorRamp(i)

            app = QgsApplication.instance()
            params = QgsSettings(
                app.qgisSettingsDirPath() + "QGIS/QGIS3.ini", QSettings.IniFormat
            )

            params.remove('colors')
            params.setValue('colors/showInMenuList', ['Insee2018 - Couleurs de base','Insee2018 Bleu—Jaune'])
            for item in QgsApplication.colorSchemeRegistry().schemes():
                QgsApplication.colorSchemeRegistry().removeColorScheme(item)

            # QgsApplication.colorSchemeRegistry().addUserSchemes()
            QgsApplication.colorSchemeRegistry().addDefaultSchemes()

            iface.messageBar().pushMessage("Palette", "L'ancienne palette a été effacée", level=Qgis.Info)

from qgis.core import *
# from qgis.gui import *
import re

@qgsfunction(args=2, group='Thematic')
def retour_ligne(values, feature, parent):
    """
        Retour à la ligne automatique

Syntaxe

 retour_ligne(LibGeo, NbCaractères)

Arguments

  LibGeo → Libellé géographique à afficher

  NbCaractères → Nombre de caractères minimum avant retour à la ligne

Exemple

        retour_ligne(LIBGEO,5)

    """
    result0 = re.sub('(.{'+str(values[1])+'}[^-]*)-','\\1-\n',values[0])
    result1 = re.sub('(.{'+str(values[1])+'}[^\\s.]*)\\s','\\1\n',result0)
    return result1

@qgsfunction(3,group='Thematic')
def  tcam(values, feature, parent):
    """
        Taux de croissance annuel moyen (en %)

Syntaxe

 tcam(Annee1, Annee2, NbAnnees)

Arguments

  Annee1 → Année de départ

  Annee2 → Année d'arrivée

  NbAnnees → Nombre d'années

Le taux de croissance annuel moyen n'est pas calculé en cas de valeur manquante

Exemple

              tcam(POP2006, PO2011,5)

    """
    try: # si une erreur est detectee dans le bloc "try", c'est le bloc "except" qui s'execute (traitement des exceptions)
        annee1 = float(values[0]) # pour passer un nombre entier en nombre a virgule flottante
        annee2 = float(values[1])
        NbAnnees = values[2]
        return ((annee2/annee1)**(1.0/NbAnnees)-1)*100
    except:
        return None

@qgsfunction(args=2, group='Thematic')
def discontinuite_relative(values, feature, parent):
    """
        Discontinuité relative entre deux variables

==>  max( var1 , var2 ) / min( var1 , var2 )

Syntaxe

 discontinuite_relative(variable1,variable2)

Arguments

  variable1, variable2 → variables à comparer

Exemple

        discontinuite_relative("VAR1","VAR2")

    """
    return max(float(values[0]),float(values[1]))/min(float(values[0]),float(values[1]))

@qgsfunction(args=2, group='Thematic')
def discontinuite_absolue(values, feature, parent):
    """
        Discontinuité absolue entre deux variables

==>  max( var1 , var2 ) - min( var1 , var2 )

Syntaxe

 discontinuite_absolue(variable1,variable2)

Arguments

  variable1, variable2 → variables à comparer

Exemple

        discontinuite_absolue("VAR1","VAR2")

    """
    return max(values[0],values[1]) - min(values[0],values[1])

@qgsfunction(2,group='Thematic')
def discontRelative(values, feature, parent):
    """
        Discontinuité relative entre deux variables

==>  max( var1 , var2 ) / min( var1 , var2 )

Syntaxe

 discontRelative(variable1,variable2)

Arguments

  variable1, variable2 → variables à comparer

Exemple

        discontRelative("VAR1","VAR2")

    """
    return max(float(values[0]),float(values[1]))/min(float(values[0]),float(values[1]))

@qgsfunction(2,group='Thematic')
def discontAbsolue(values, feature, parent):
    """
        Discontinuité absolue entre deux variables

==>  max( var1 , var2 ) - min( var1 , var2 )

Syntaxe

 discontAbsolue(variable1,variable2)

Arguments

  variable1, variable2 → variables à comparer

Exemple

        discontAbsolue("VAR1","VAR2")

    """
    return max(values[0],values[1]) - min(values[0],values[1])

@qgsfunction(1,group='Thematic')
def extraire_libgeo(values, feature, parent):
    """
        Extraire un libellé géographique d'une chaine de caractères de type de type Corse-du-Sud (2A)

Syntaxe

 extraire_libgeo(ChaineCaractere)

Arguments

  ChaineCaractere → Chaine de caractères contenant un libellé géographique + un code géographique entre parenthèses

Exemple

        extraire_libgeo(DEP)

    """
    return re.search('(.+)\s\(',values[0]).group(1)


'''

'''

def check(nums,k):
    nums.sort()
    if nums[0]==0:
        return False
    for i in range(1,len(nums)):
        if nums[i]==0:
            return False
        if nums[i]>nums[i-1]+k:
            return False
    return True

def main():
    T=int(input())
    for _ in range(T):
        n,k=map(int,input().split())
        nums=list(map(int,input().split()))
        if check(nums,k):
            print("YES")
        else:
            print("NO")

main()


from rest_framework import status
from rest_framework.generics import CreateAPIView, RetrieveAPIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny

from user.serializers import UserRegistrationSerializer
from user.serializers import UserLoginSerializer
from user.models import User

class UserRegistrationView(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserRegistrationSerializer
    permission_classes = (AllowAny,)

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        response = {
            'success' : 'True',
            'status code' : status.HTTP_200_OK,
            'message': 'User registered  successfully',
            }
        status_code = status.HTTP_200_OK
        return Response(response, status=status_code)

class UserLoginView(RetrieveAPIView):
    queryset = User.objects.all()
    permission_classes = (AllowAny,)
    serializer_class = UserLoginSerializer
    #lookup_field = 'id'

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        response = {
            'success' : 'True',
            'status code' : status.HTTP_200_OK,
            'message': 'User logged in  successfully',
            'token' : serializer.data['token'],
            }
        status_code = status.HTTP_200_OK

        return Response(response, status=status_code)


import os
from string import ascii_letters, digits, punctuation

import numpy as np
import requests

_char_decode = dict(enumerate(sorted(set(ascii_letters + digits + punctuation + " \n"))))
_char_encode = {char: i for i, char in _char_decode.items()}

def char_tknzr(txt: str):
    return [_char_encode[char] for char in txt if char in _char_encode]

DATA_PATH = os.path.join(os.path.dirname(__file__), "datasets", "shakespeare")

def get_shakespeare_data():
    """Inspired from https://github.com/karpathy/nanoGPT/"""
    raw_path = os.path.join(DATA_PATH, "raw.txt")
    train_path = os.path.join(DATA_PATH, f"train.npy")
    test_path = os.path.join(DATA_PATH, f"test.npy")

    # if path is not even there, download all data
    if not os.path.exists(DATA_PATH):
        print("Downloading raw Shakespeare texts")
        url = "https://raw.githubusercontent.com/karpathy/char-rnn/master/data/tinyshakespeare/input.txt"
        os.makedirs(DATA_PATH, exist_ok=True)
        text = requests.get(url, timeout=60).text
        with open(raw_path, "w+", encoding="utf8") as f:
            f.write(text)

    # attempt to find cached version for current tokenizer
    if not os.path.exists(train_path) or not os.path.exists(test_path):
        print("Tokenizing Shakespeare texts")
        # load text
        with open(raw_path, encoding="utf8") as f:
            text = "".join(f.readlines())
        i = int(0.8*len(text))
        # encode text
        x = np.array(char_tknzr(text[:i]), dtype=np.uint16)
        x_test = np.array(char_tknzr(text[i:]), dtype=np.uint16)
        # map memory
        mem = np.memmap(train_path, dtype=np.uint16, mode="w+", shape=x.shape)
        mem[:] = x
        mem = np.memmap(test_path, dtype=np.uint16, mode="w+", shape=x_test.shape)
        mem[:] = x_test

    # at this point we know that the binfile was properly created so we load it
    return {"train": np.memmap(train_path, dtype=np.uint16, mode="r"),
            "val": np.memmap(test_path, dtype=np.uint16, mode="r")}


#!/usr/bin/env python
import random, sys

def main():
    i = 1
    n = random.randint(1, 100)
    m = None
    while m == None or m != n:
        sys.stdin.flush()
        entry = input(f'[{i}] Entrer un nombre [1-100] ')
        i += 1
        if entry == '':
            print('abandon...', end='')
            sys.stdin.read(1)
            exit(0)
        try:
            m = int(entry)
        except:
            print('SVP entrez un nombre valide')
            continue
        if m < 1 or m > 100:
            print('Min: 1, Max: 100')
        print('Trop petit' if m < n else 'Trop grand' if m > n else 'OK')

if __name__ == "__main__":
    main()


n = int(input())
down = set()
numbers = []

def dfs():
    if numbers:
        num = ""
        for m in numbers:
            num += str(m)

        down.add(int(num))

    for i in range(10):
        if not numbers or numbers[-1] > i:
            numbers.append(i)
            dfs()
            numbers.pop()

dfs()

if len(down) >= n:
    print(sorted(down)[n-1])
else:
    print(-1)

백준/Gold/1174. 줄어드는 수/줄어드는 수.py


import pygame as pg

def array_to_move(x, y):
    letters = ["a", "b", "c", "d", "e", "f", "g", "h"]
    move = ""
    x += 1
    y += 1
    move += letters[y]
    if x == 7:
        x = 1
    elif x == 6:
        x = 2
    elif x == 5:
        x = 3
    elif x == 3:
        x = 5
    elif x == 2:
        x = 6
    elif x == 1:
        x = 7
    elif x == 0:
        x = 8
    move += str(x)
    return move

def get_image_figure(name, resolution):
    resolution = resolution // 8
    img_name = 'slike/' + name + '.png'
    image = pg.image.load(img_name)
    image = pg.transform.scale(image, resolution)
    return image

def convert_coordinates_to_array(x, y, square_size):
    x = 0
    y = 0
    ss_1 = square_size
    ss_2 = 0
    for i in range(0, 8):
        if x <= ss_1:
            y = ss_2
            break
        else:
            ss_1 += square_size
            ss_2 += 1
    ss_1 = square_size
    ss_2 = 0
    for i in range(0, 8):
        if y <= ss_1:
            x = ss_2
            break
        else:
            ss_1 += square_size
            ss_2 += 1
    return x, y


import autosklearn.classification
from collections import Counter
import numpy as np
import copy
from mlxtend.classifier import EnsembleVoteClassifier
from sklearn.dummy import DummyClassifier
from package import modelwrapper as mw, ensembleselection as es
from sklearn.model_selection import StratifiedKFold

class AutoShardedClassifier:

    def __init__(self, num_shards=np.inf, ensemble_strategy=1):
        self.ml_algorithm = None
        self.num_shards = num_shards
        self.X_train = None
        self.y_train = None
        self.shard_data_dict = {}
        self.shard_model_dict = {}
        self.shard_model_weight_dict = {}
        self.data_to_shard_dict = {}
        self.cur_train_ids = []
        self.default_class = None
        self.ensemble = None
        self.num_classes = None
        if ensemble_strategy not in [1, 2, 3, 4, 5]:
            ensemble_strategy = 1
        self.ensemble_strategy = ensemble_strategy
        self.X_dummy = None
        self.y_dummy = None
        if ensemble_strategy is 4:
            self.all_ensembles = [None] * 3

    def fit(self, X, y):
        self.X_train = copy.deepcopy(X)
        self.y_train = copy.deepcopy(y)
        self.num_classes = len(set(self.y_train))
        self.X_dummy = np.zeros(shape=(self.num_classes, len(X[0])))
        self.y_dummy = np.asarray(list(range(self.num_classes)))
        self.default_class = Counter(y).most_common(1)[0][0]
        # print(self.num_shards)
        # print(Counter(y).most_common()[-1][1])
        self.num_shards = min(self.num_shards, Counter(y).most_common()[-1][1])
        # print(self.num_shards)
        self.create_training_subsets_for_shards()
        self.ml_algorithm = autosklearn.classification.AutoSklearnClassifier(time_left_for_this_task=900,
                                                                             ensemble_size=self.num_shards,
                                                                             # ensemble_nbest=max(2*self.num_shards, 50),
                                                                             ensemble_memory_limit=4096,
                                                                             include_preprocessors=["no_preprocessing"],
                                                                             exclude_estimators=[
                                                                             # "random_forest",
                                                                             # "adaboost",
                                                                             # "extra_trees",
                                                                             # "gradient_boosting",
                                                                             "k_nearest_neighbors"]
                                                                             )
        best_models_ensemble = self.ml_algorithm.fit(self.X_train, self.y_train).get_models_with_weights()
        shards_model_assignment_sequence = list(range(self.num_shards))
        shards_model_assignment_sequence_idx = 0
        for i in range(len(best_models_ensemble)):
            num_cur_model_shards = int(self.num_shards * best_models_ensemble[i][0])
            for j in range(num_cur_model_shards):
                shard_num = shards_model_assignment_sequence[shards_model_assignment_sequence_idx]
                self.shard_model_dict[shard_num] = mw.modelWrapper(best_models_ensemble[i][1], self.num_classes)
                self.shard_model_dict[shard_num].fit(self.X_train[self.shard_data_dict[shard_num]],
                                                     self.y_train[self.shard_data_dict[shard_num]])
                self.shard_model_weight_dict[shard_num] = 1
                shards_model_assignment_sequence_idx += 1

        # Create ensemble
        if self.ensemble_strategy is 4:
            self.create_all_ensembles()
        else:
            self.create_ensemble()

    def predict(self, X):
        if self.ensemble_strategy is 4:
            pred = []
            for i in range(3):
                pred.append(self.all_ensembles[i].predict(X))
            return pred
        return self.ensemble.predict(X)

    def unlearn(self, X_y_ids):
        shard_num = self.getShardNum(X_y_ids)
        for i in range(len(X_y_ids)):
            self.shard_data_dict[shard_num[i]].remove(X_y_ids[i])
            self.cur_train_ids.remove(X_y_ids[i])
        self.default_class = Counter(self.y_train[self.cur_train_ids]).most_common(1)[0][0]
        # Refitting shards after unlearning - vanilla implementation: call fit() for every shard's model
        for shard_i in list(set(shard_num)):
            isDummy, dummy_model, pred = self.checkForDummy(self.y_train[self.shard_data_dict[shard_i]])
            if isDummy:
                print("dummy created")
                # dummy fit just to handle errors
                self.shard_model_dict[shard_i] = mw.modelWrapper(dummy_model, self.num_classes)
                self.shard_model_dict[shard_i].fit(self.X_dummy, self.y_dummy)
            else:
                self.shard_model_dict[shard_i].fit(self.X_train[self.shard_data_dict[shard_i]],
                                                   self.y_train[self.shard_data_dict[shard_i]])
        # Create ensemble
        if self.ensemble_strategy is 4:
            self.create_all_ensembles()
        elif self.ensemble_strategy is not 5:
            self.create_ensemble()

    def create_training_subsets_for_shards(self):
        self.cur_train_ids = list(range(len(self.y_train)))
        if self.num_shards is 1:
            self.shard_data_dict[0] = copy.deepcopy(self.cur_train_ids)
            self.data_to_shard_dict = {it: 0 for it in range(len(self.y_train))}
        else:
            skf = StratifiedKFold(n_splits=self.num_shards, shuffle=True, random_state=0)
            shard_num = 0
            for train_idx, test_idx in skf.split(self.X_train, self.y_train):
                self.shard_data_dict[shard_num] = copy.deepcopy(test_idx.tolist())
                for i in test_idx:
                    self.data_to_shard_dict[i] = shard_num
                shard_num += 1

    def create_ensemble(self):
        if self.ensemble_strategy is 1:
            self.ensemble = EnsembleVoteClassifier(clfs=list(self.shard_model_dict.values()),
                                                   voting='soft',
                                                   weights=list(self.shard_model_weight_dict.values()),
                                                   refit=False)
            self.ensemble.fit(self.X_dummy, self.y_dummy)
        elif self.ensemble_strategy is 2:
            self.ensemble = es.EnsembleSelectionClassifier(maxIter=np.inf).getEnsemble(
                models=list(self.shard_model_dict.values()),
                X=self.X_train[self.cur_train_ids],
                y=self.y_train[self.cur_train_ids])
            self.ensemble.fit(self.X_dummy, self.y_dummy)
        else:
            self.ensemble, new_weights = es.EnsembleSelectionClassifier(maxIter=np.inf).getEnsemble(
                models=list(self.shard_model_dict.values()),
                X=self.X_train[self.cur_train_ids],
                y=self.y_train[self.cur_train_ids],
                initial_weights=list(self.shard_model_weight_dict.values()),
                ret_weights=True)
            self.ensemble.fit(self.X_dummy, self.y_dummy)
            # now update weights
            for i in range(self.num_shards):
                self.shard_model_weight_dict[i] = new_weights[i]

    def create_all_ensembles(self):
        self.all_ensembles[0] = EnsembleVoteClassifier(clfs=list(self.shard_model_dict.values()),
                                                       voting='soft',
                                                       weights=[1] * self.num_shards,
                                                       refit=False)
        self.all_ensembles[0].fit(self.X_dummy, self.y_dummy)

        self.all_ensembles[1] = es.EnsembleSelectionClassifier(maxIter=np.inf).getEnsemble(
            models=list(self.shard_model_dict.values()),
            X=self.X_train[self.cur_train_ids],
            y=self.y_train[self.cur_train_ids])
        self.all_ensembles[1].fit(self.X_dummy, self.y_dummy)

        self.all_ensembles[2], new_weights = es.EnsembleSelectionClassifier(maxIter=np.inf).getEnsemble(
            models=list(self.shard_model_dict.values()),
            X=self.X_train[self.cur_train_ids],
            y=self.y_train[self.cur_train_ids],
            initial_weights=list(self.shard_model_weight_dict.values()),
            ret_weights=True)
        self.all_ensembles[2].fit(self.X_dummy, self.y_dummy)
        # now update weights
        for i in range(self.num_shards):
            self.shard_model_weight_dict[i] = new_weights[i]

    def getShardNum(self, idx):
        return [self.data_to_shard_dict[id_i] for id_i in idx]

    def checkForDummy(self, y):
        if len(y) is 0:
            return True, DummyClassifier(strategy="constant", constant=self.default_class), self.default_class
        elif len(Counter(y).keys()) is 1:
            return True, DummyClassifier(strategy="constant", constant=y[0]), y[0]
        return False, None, None


import sys
import os
from argparse import ArgumentParser
from argparse import ArgumentError
from contextlib import contextmanager
import unittest
from os.path import dirname
from os.path import join
from multiprocessing import Process
from subprocess import Popen
from subprocess import PIPE
from tempfile import mkdtemp

from explosive.fuse import ctrl

path = lambda p: join(dirname(__file__), 'data', p)

# mixture of unicode and str in python2.7 version of argparse means that
# default IO classes would be painful to use; use my own thing here.
class Input(object):

    def __init__(self, inputs):
        self.inputs = inputs.splitlines()

    def readline(self):
        if self.inputs:
            return self.inputs.pop(0)
        else:
            raise EOFError()

class Output(object):

    def __init__(self):
        self.items = []

    def write(self, s):
        self.items.append(s)

    def flush(self):
        pass

@contextmanager
def capture_stdio(inputs=''):
    dummy_in, dummy_out, dummy_err = Input(inputs), Output(), Output()
    curr_in, curr_out, curr_err = sys.stdin, sys.stdout, sys.stderr
    try:
        sys.stdin, sys.stdout, sys.stderr = dummy_in, dummy_out, dummy_err
        yield dummy_in, dummy_out, dummy_err
    finally:
        sys.stdin, sys.stdout, sys.stderr = curr_in, curr_out, curr_err

class PathMakerChoiceTestCase(unittest.TestCase):

    def test_argument_error(self):
        ap = ArgumentParser()
        action = ctrl._PathmakerChoiceStoreAction(None, 'dummy', 1)
        with self.assertRaises(ArgumentError) as cm:
            action(ap, ap, 'nothing', None)

    def test_argument_success(self):
        ap = ArgumentParser()
        action = ctrl._PathmakerChoiceStoreAction(None, 'dummy', 1)
        action(ap, ap, 'flatten', None)
        self.assertEqual(ap.dummy.__name__, 'flatten')

class IntegrationTestCase(unittest.TestCase):

    def test_simple(self):
        with capture_stdio() as stdio:
            with self.assertRaises(SystemExit):
                ctrl.main([])

    def test_layout_help(self):
        with capture_stdio() as stdio:
            with self.assertRaises(SystemExit):
                ctrl.main(['--layout-info'])
            # perhaps include actual equality check.

    def test_version(self):
        with capture_stdio() as stdio:
            with self.assertRaises(SystemExit):
                ctrl.main(['--version'])
            # perhaps include actual equality check.

    def test_failure(self):
        with capture_stdio() as stdio:
            with self.assertRaises(SystemExit):
                ctrl.main(['-d', '/tmp/to/no/such/dir', 'somezip.zip'])

    def test_failure_with_manager(self):
        with capture_stdio() as stdio:
            with self.assertRaises(SystemExit):
                ctrl.main(['-m', '-d', '/tmp/to/no/such/dir', 'somezip.zip'])

    def test_invalid_layout_choice(self):
        with capture_stdio() as stdio:
            in_, out, err = stdio
            with self.assertRaises(SystemExit):
                ctrl.main(['-l', 'nothing'])
            self.assertTrue(err.items[-1].endswith(
                "error: argument -l/--layout: "
                "invalid choice: 'nothing' (choose from "
                "'codepage', 'default', 'flatten', 'junk')\n",
            ))

    def test_invalid_layout_arg(self):
        with capture_stdio() as stdio:
            in_, out, err = stdio
            with self.assertRaises(SystemExit):
                ctrl.main(['-l', 'junk:hi'])
            self.assertTrue(err.items[-1].endswith(
                "error: argument -l/--layout: "
                "invalid argument to 'junk': 'keep' must be a number\n"
            ))

# Acceptance testing
# to enable, do something like:
# $ ACCEPTANCE=1 python setup.py test
#
# Disabling by default due to issues with getting this working reliably
# with other CI systems.

@unittest.skipUnless(os.environ.get('ACCEPTANCE'),
                     'skipping acceptance test by default')
class AcceptanceTestCase(unittest.TestCase):

    def setUp(self):
        self.mountpoint = mkdtemp()
        # maybe validate that this works?
        # subprocess.check_output(["fusermount", "-V"])

    def tearDown(self):
        sp = Popen(['fusermount', '-u', self.mountpoint],
                   stdout=PIPE, stderr=PIPE)
        result = sp.communicate()

    def test_success_basic(self):
        dummy1 = path('demo1.zip')
        dummy2 = path('demo2.zip')

        # This will terminate, so spawn a separate process.
        p = Process(
            target=ctrl.main, args=(['-d', self.mountpoint, dummy1, dummy2],))
        p.start()
        p.join()

        self.assertEqual(
            sorted(os.listdir(self.mountpoint)),
            ['demo1.zip', 'demo2.zip'],
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo1.zip'))),
            ['file1', 'file2', 'file3', 'file4', 'file5', 'file6']
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo2.zip'))),
            ['demo']
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo2.zip', 'demo'))),
            ['file1', 'file2', 'file3', 'file4', 'file5', 'file6']
        )

    def test_success_managed_default(self):
        dummy1 = path('demo1.zip')
        dummy2 = path('demo2.zip')

        # This will terminate, so spawn a separate process.
        p = Process(
            target=ctrl.main, args=(['-md', self.mountpoint, dummy1, dummy2],))
        p.start()
        p.join()

        self.assertEqual(
            sorted(os.listdir(self.mountpoint)),
            ['.manager', 'demo1.zip', 'demo2.zip'],
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, '.manager'))),
            ['demo1.zip', 'demo2.zip']
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo1.zip'))),
            ['file1', 'file2', 'file3', 'file4', 'file5', 'file6']
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo2.zip'))),
            ['demo']
        )

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, 'demo2.zip', 'demo'))),
            ['file1', 'file2', 'file3', 'file4', 'file5', 'file6']
        )

        os.unlink(join(self.mountpoint, '.manager', 'demo1.zip'))
        self.assertEqual(
            sorted(os.listdir(self.mountpoint)),
            ['.manager', 'demo2.zip'],
        )

        os.symlink(dummy1, join(self.mountpoint, '.manager', 'archive.zip'))

        self.assertEqual(
            sorted(os.listdir(join(self.mountpoint, '.manager'))),
            ['archive.zip', 'demo2.zip']
        )

        self.assertEqual(
            sorted(os.listdir(self.mountpoint)),
            ['.manager', 'demo1.zip', 'demo2.zip'],
        )

        with self.assertRaises(OSError):
            os.symlink(dummy1, join(
                self.mountpoint, '.manager', 'alternate.zip'))


class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        length = 0
        maxLength = 0
        left = 0
        right = 0
        d = {}
        for i in range(len(s)):
            d[s[i]] = 0

        while right < len(s):
            while right< len(s):
                d[s[right]] +=1
                if d[s[right]]>1:
                    break
                length +=1
                right +=1
            #print("# 1 -left : %2d, right : %2d, length: %2d" % (left, right, length))
            if length> maxLength: maxLength = length
            while length >0:
                d[s[left]] -=1
                length -=1
                left +=1
                if d[s[left-1]] > 0:
                    d[s[left-1]]-=1
                    break
            #print("# 2 -left : %2d, right : %2d, length: %2d" % (left, right, length))
        return maxLength

instance = Solution()
print(instance.lengthOfLongestSubstring('aab'))
print(instance.lengthOfLongestSubstring('pwwkew'))


if __name__ == "__main__":
  import sys
  import os
  sys.path.insert(0,os.path.abspath("../../../"))

from bmark.bmarks.common import *
from lang.prog import MathProg
from ops import op, opparse
import bmark.menvs as menvs
from bmark.bmarks.other.bbsys import build_std_bb_sys

def model():
  params = {
    'meas_noise':0.0,
    'proc_noise':1.0,
    'XL0':0.0,
    'XD0':0.5,
    'P0':0.3,
    'Z0':0.1,
    'flow':-0.1,
    'influx':0.2,
    "one":0.9999
  }
  # water with an unknown fill rate.
  prob = MathProg("KWaterLeak")
  params['Q'] = params['meas_noise']
  params['Rinv'] = 1.0/params['proc_noise']
  params['nRinv'] = -1.0/params['proc_noise']

  dZ = parse_diffeq("{influx}+{flow}*Z", \
                    "Z0", \
                    ":z", \
                    params)
  E = parse_fn("{one}*Z+{one}*(-XL)",params)
  dXL = parse_diffeq("{influx} + {one}*(-XD)*XL + {Rinv}*P11*E",
                     "XL0",\
                     ":a", \
                     params)

  dXD = parse_diffeq("{Rinv}*P12*E",
                     "XD0",
                     ":b",
                     params)

  dP11 = parse_diffeq("2.0*P11*(-XD) + {nRinv}*P11*P11", \
                      "P0", \
                      ":p11",
                      params)
  dP12 = parse_diffeq("{one}*(-XD)*P12 + {one}*(-XL)*P22 + {nRinv}*P12*P11", \
                      "P0", \
                      ":p12", \
                      params)
  dP22 = parse_diffeq("{nRinv}*P12*P12", \
                      "P0", \
                      ":p12", \
                      params)

  prob.bind("XL",dXL)
  prob.bind("Z",dZ)
  prob.bind("E",E)
  prob.bind("XD",dXD)
  prob.bind("P11",dP11)
  prob.bind("P12",dP12)
  prob.bind("P22",dP22)
  measure_var(prob,"XL","PROB")

  prob.set_interval("XL",0,2.5)
  prob.set_interval("XD",0,0.5)
  prob.set_interval("P11",0,1.5)
  prob.set_interval("P12",0,1.5)
  prob.set_interval("P22",0,1.5)
  prob.set_interval("Z",0,2.5)

  prob.set_max_sim_time(50)
  prob.compile()
  menv = menvs.get_math_env('t50')
  return menv,prob

def execute():
  menv,prob = model()
  plot_diffeq(menv,prob)

if __name__ == "__main__":
  execute()


# pylint: disable=missing-module-docstring
import os
from pathlib import Path
from textwrap import dedent

import yaml

ROOT_FOLDER = os.environ.get("DIRLISTER_TARGET", "/")

def load_filter() -> dict:
    """example filter.yaml:
    filters:
      - "[tag]"
      - "sausage"
      - 2020

    this filter would turn a file or directory that looks like this:
      "abc [tag] def sausage ghi 2020"
    into this:
      "abc def ghi"
    """
    filters = {}
    filter_file = ""

    filter_file = Path("filter.yaml")
    if not filter_file.exists():
        default_content = dedent(
            """
            filters:
              - "make a yaml list of things to filter from files and directory names"
            """
        ).lstrip()

        filter_file.write_text(default_content, encoding="utf-8")

    filter_raw = filter_file.read_text(encoding="utf-8")

    filters = yaml.safe_load(filter_raw)

    return filters


"""Validation tools for the datavalidator package."""
import json
import re
import html
from typing import Any, Callable, Union, Optional
from .types import RangeT, SetT, PolarT, PatternT, EnumT, XT, YT
from .exceptions import DataValidationError

class ValidationResult:
    """Data validation result.

    Each ValidationResult represents the result of a data validation attempt in a
    Validator. The ValidationResult can be queried for details on the data that was
    validated, whether it passed/failed validation, what the requirements for validation
    were, etc. A ValidationResult will evaluate to True if the validation has succeeded
    and to False if it has failed.
    """

    success: bool
    """Whether the data has been succeessfully validated or not."""

    type_: Any
    """The internal data type indicated for validation."""

    typedesc: str
    """A user-directed description of the type of data being validated."""

    constraint: Optional[Union[PatternT, RangeT, SetT, PolarT, PatternT, EnumT, bool]]
    """The constraint, if any, which was used to validate the data."""

    data: Any
    """The data itself, possibly cast.

    This is the data post-casting if force- or softcasting were used, and can be
    used to automatically ensure typecasting or type-narrowing for data storage.
    For the raw data pre-casting use the `raw_data` attribute.
    """

    rawdata: Any
    """The raw data, as it was passed to the validator.

    This is always the data as it was passed to the Validator, irrespective of
    whether forcecasting or softcasting were applied.
    """

    casting: bool
    """Whether the data in `data` was cast or not.

    Note that this does not necessarily mean that casting was necessary, e.g.
    an integer that was passed to a Validator's `vint()` method will still
    have been cast to int() and set the casting attribute to True despite
    being of type int before.
    """

    def __init__(
        self,
        success: bool,
        type_: Any,
        typedesc: str,
        constraint: Optional[
            Union[PatternT, RangeT, SetT, PolarT, PatternT, EnumT, bool]
        ],
        data: Any,
        rawdata: Any,
        casting: bool,
    ):
        """Constructs a new ValidationResult.

        Args:
            success: Whether the validaton has succeeded or failed.
            type_: The built-in data type against which validation was carried out.
            typedesc: A short user-intelligible description of the data's type.
            constraint: A constraint data type appropriate to the type of the data,
                see also the `types` submodule.
            data: The data that was evaluated (after casting if the forcecasting and/or
                softcasting options were active.)
            rawdata: The raw, uncast data as it was passed to the validation method.
            casting: Whether casting was applied to `rawdata` to yield `data`.
        """
        self.success = success
        self.type_ = type_
        self.typedesc = typedesc
        self.constraint = constraint
        self.data = data
        self.rawdata = rawdata
        self.casting = casting

    def tostring(self) -> str:
        """Returns string explanation of the data validation result."""
        polarity = "is" if self.success else "is not"
        data = self.data if self.success else self.rawdata
        string = (
            f"`{repr(data)}` {polarity} a valid {self.typedesc} of type {self.type_}."
        )
        if not self.success:
            string += f" Must match constraint: `{repr(self.constraint)}`."
        return string

    def tohtml(self) -> str:
        """Returns HTML formatted explanation of the data validation result."""
        output: list[str] = []
        output.append('
')
        data = self.data if self.success else self.rawdata
        data = html.escape(repr(data), True)
        output.append(f'{data}')
        if self.success:
            output.append('is')
        else:
            output.append('is not')
        output.append("a valid")
        typedesc = html.escape(self.typedesc, True)
        output.append(f'{typedesc}')
        output.append("of type")
        type_ = html.escape(repr(self.type_), True)
        output.append(f'{type_}.')
        if not self.success:
            output.append("Must match constraint:")
            if isinstance(self.constraint, str):
                constraint = html.escape(self.constraint, True)
            else:
                constraint = html.escape(repr(self.constraint))
            output.append(f'{constraint}')
        output.append("
")
        return " ".join(output)

    def tojson(self) -> str:
        """Returns a JSON representation of the data validation result."""
        data = self.data
        if not isinstance(self.data, (str, int, float, bool, type(None))):
            try:
                json.dumps(data)
            except TypeError:
                data = repr(self.data)

        return json.dumps(
            {
                "isvalid": self.success,
                "type": self.type_,
                "typedesc": self.typedesc,
                "constraint": self.constraint,
                "data": data,
            }
        )

    def __str__(self) -> str:
        """Returns a string representation of the data validation result."""
        return self.tostring()

    def __bool__(self) -> bool:
        """Returns True if the validation was successful, False otherwise."""
        return self.success

    def __repr__(self) -> str:
        """Returns a python-style representation of the data validation result object."""
        indent = "    "
        string = f"{__class__.__name__}(\n{indent}{repr(self.success)},\n{indent}"
        string += f"{repr(self.type_)},\n{indent}{repr(self.typedesc)},\n"
        string += f"{indent}{repr(self.constraint)},"
        return string + f"\n{indent}{repr(self.data)}\n)"

class Validator:
    """Data validation interface.

    A Validator offers a convenient interface for validating a set of data points,
    of the same or different types. The Validator will store any failed validation
    results, can optionally force casting of the data to a specific type, can be evaluated
    for success in a boolean expression, and allows for the conditional raising of a
    DataValidationError exception if any validation attempts have failed.

    A single Validator should only be used once for a closed set of data, as reuse
    will add the results to the existing Validator and always evaluate False if it has
    previously had unsuccessful validation attempts (though under some circumstances, e.g.
    the successive building of datasets with late repairs, this may be desirable).
    """

    results: list[ValidationResult]
    failed: list[ValidationResult]
    successful: list[ValidationResult]
    forcecast: bool
    ignorecase: bool

    def __init__(self, forcecast: bool = False, ignorecase: bool = False):
        """Constructs a new Validator.

        Args:
            forcecast: Whether to force casting of the data arguments to the validation
                methods to the indicated type (e.g. str for .validatestring()). This
                will set the default behaviour for validation calls, but can be
                overwritten by passing the named argument forcecast=True or
                forcecast=False on individual method calls.
                For some methods, e.g. polars and enums, casting is done by passing the
                matched value rather than typecasting.
            ignorecase: Whether to ignore case in string comparisons. If true, strings
                will be compared in all uppercase, and regular expression matches will
                be passed the IGNORECASE flag. Can be overwritten on each validation call
                by passing ignorecase=True/False. Default value: False.
        """
        self.results = []
        self.failed = []
        self.successful = []
        self.forcecast = forcecast
        self.ignorecase = ignorecase

    def __forcecast(self, overwrite: Optional[bool] = None) -> bool:
        if overwrite is not None:
            return overwrite
        return self.forcecast

    def __ignorecase(self, overwrite: Optional[bool] = None):
        if overwrite is not None:
            return overwrite
        return self.ignorecase

    def __casefolddict(self, dict_: dict[XT, YT]) -> dict[XT, YT]:
        return {self.__casefoldifstr(key): value for key, value in dict_.items()}

    def __casefoldifstr(self, x: XT) -> XT:
        if isinstance(x, str):
            return x.casefold()
        return x

    def __trycall(
        self, func: Callable[..., XT], *args: Any, **kwargs: dict[Any, Any]
    ) -> Optional[XT]:
        """Returns result of func() if possible, None if an Exception is raised."""
        try:
            return func(*args, **kwargs)
        except Exception:
            return None

    def __condcast(
        self, type_: Callable[..., XT], data: YT, overwrite: Optional[bool] = None
    ) -> Optional[Union[XT, YT]]:
        """Conditionally casts data to a type.

        Attempts to cast `data` to `type_` if, taking into account `overwrite`,
        forcecasting applies. Returns `data` itself if forcecasting doesn't apply,
        and None if forcecasting applies but `data` cannot be cast to `type_`.
        """
        if self.__forcecast(overwrite):
            return self.__trycall(type_, data)
        return data

    def __storeresult(self, result: ValidationResult):
        self.results.append(result)
        if not result:
            self.failed.append(result)
        else:
            self.successful.append(result)

    def vstr(
        self,
        typedesc: str,
        constraint: PatternT,
        data: Any,
        forcecast: Optional[bool] = None,
        ignorecase: Optional[bool] = None,
        flags: Union[re.RegexFlag, int] = 0,
    ) -> ValidationResult:
        r"""Validates a string against a regular expression pattern.

        Args:
            typedesc: An end-user intelligible description of the desired data type, e.g.
                "User ID" or "postcode".
            constraint: A regular expression to match the string against. Important: Note
                that the regular expression will implicitly be enclosed by \A and \Z to
                match the beginning and end of the string. These thus need not be
                specified in the pattern provided.
            data: The data to be validated.
            forcecast: Optional argument to overwrite the validator's default setting for
                forced casting of data arguments.
            ignorecase: Optional argument to overwrite the validator's default setting
                for case sensitivity.
            flags: Additional regex flags to be passed to re.match().
        """
        cdata = data
        try:
            if not isinstance(data, str):
                cdata = str(data)
            flags = re.IGNORECASE | flags if self.__ignorecase(ignorecase) else flags
            cmp = bool(
                re.match(r"\A{pattern}\Z".format(pattern=constraint), cdata, flags=flags)
            )
        except TypeError:
            cmp = False
        validation = ValidationResult(
            cmp,
            str,
            typedesc,
            constraint,
            self.__condcast(str, data, forcecast),
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def vint(
        self,
        typedesc: str,
        constraint: RangeT,
        data: Any,
        forcecast: Optional[bool] = None,
    ) -> ValidationResult:
        r"""Validates an integer against an inclusive range of integers or floats.

        Args:
            typedesc: An end-user intelligible description of the desired data type, e.g.
                "User ID" or "postcode".
            constraint: A two member tuple or list of integers where the first element
                represents the inclusive lower bound and the second member the inclusive
                upper bound of the permissible range of integer values. For example,
                (3, 5) would successfully validate the data inputs 3, 4, 5, but fail
                validation for 2 or 6.
            data: The data to be validated.
            forcecast: Optional argument to overwrite the validator's default setting for
                forced casting of data arguments.
        """
        cdata = data
        try:
            if not isinstance(data, int):
                cdata = int(data)
            cmp = min(constraint) <= cdata <= max(constraint)
        except (TypeError, ValueError):
            cmp = False
        validation = ValidationResult(
            cmp,
            int,
            typedesc,
            constraint,
            self.__condcast(int, data, forcecast),
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def vfloat(
        self,
        typedesc: str,
        constraint: RangeT,
        data: Any,
        forcecast: Optional[bool] = None,
    ):
        r"""Validates a float against an inclusive range of integers or floats.

        Args:
            typedesc: An end-user intelligible description of the desired data type, e.g.
                "User ID" or "postcode".
            constraint: A two member tuple or list of integers where the first element
                represents the inclusive lower bound and the second member the inclusive
                upper bound of the permissible range of integer values. For example,
                (3, 5) would successfully validate the data inputs 3, 4, 5, but fail
                validation for 2 or 6.
            data: The data to be validated.
            forcecast: Optional argument to overwrite the objects default setting for
                forced casting of data arguments.
        """
        cdata = data
        try:
            if not isinstance(data, float):
                cdata = float(data)
            cmp = min(constraint) <= cdata <= max(constraint)
        except TypeError:
            cmp = False
        validation = ValidationResult(
            cmp,
            float,
            typedesc,
            constraint,
            self.__condcast(float, data, forcecast),
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def vbool(
        self,
        typedesc: str,
        constraint: bool,
        data: Any,
        forcecast: Optional[bool] = None,
    ):
        """Validates a bool.

        Args:
            typedesc: An end-user intelligible description of the desired data type, e.g.
                "User ID" or "postcode".
            constraint: A boolean that must be matched, or None to just validate any bool.
            data: The data to be validated.
            forcecast: Optional argument to overwrite the objects default setting for
                forced casting of data arguments.
        """
        cdata = data
        try:
            if not isinstance(data, bool):
                cdata = bool(data)
            cmp = True
            if constraint is not None:
                cmp = (cdata == constraint)
        except TypeError:
            cmp = False
        validation = ValidationResult(
            cmp,
            bool,
            typedesc,
            constraint,
            self.__condcast(bool, data, forcecast),
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def vpolar(
        self,
        typedesc: str,
        constraint: PolarT,
        data: Any,
        forcecast: Optional[bool] = None,
        ignorecase: Optional[bool] = None,
    ) -> ValidationResult:
        r"""Validates a string against two sets of polar terms.

        Checkes whether data is in either of two sets of polar opposition terms. If the
        forcecast option is active, membership in the first of the two sets results in
        casting to True, membership in the second set to False, and memebership in
        neither set to None. Validation is successful if data is contained in either of
        the two sets, and unsuccessful otherwise.

        Args:
            typedesc: An end-user intelligible description of the desired data type, e.g.
                "User ID" or "postcode".
            constraint: A two member tuple or list of containers of any type (must support
                membership testing with `in`). The first member is a container of
                acceptable truthy values, the second is a container of acceptable falsy
                values. Note that python built-in boolean types True and False are always
                validated as correct.
            data: The data to be validated.
            forcecast: Optional argument to overwrite the objects default setting for
                forced casting of data arguments.
            ignorecase: Optional argument to overwrite the validator's default setting
                for case sensitivity.
        """
        cdata = data
        cval = None
        if isinstance(data, str) and self.__ignorecase(ignorecase):
            cdata = data.casefold()
            if cdata in set(map(self.__casefoldifstr, constraint[0])):
                cval = True
            elif cdata in set(map(self.__casefoldifstr, constraint[1])):
                cval = False
        else:
            if cdata in constraint[0]:
                cval = True
            elif cdata in constraint[1]:
                cval = False
        cmp = cval is not None
        validation = ValidationResult(
            cmp,
            PolarT,
            typedesc,
            constraint,
            cval if self.__forcecast(forcecast) else data,
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def venum(
        self,
        typedesc: str,
        constraint: EnumT,
        data: Any,
        forcecast: Optional[bool] = None,
        ignorecase: Optional[bool] = None,
    ) -> ValidationResult:
        """Validates a string against a key:value enumerable.

        Checks whether `data` is either contained in the keys or the values
        of the enumerable. If forcecasting is used, it casts to the *value*
        that was matched (not the key), or to None if no match was found.
        """
        cdata = data
        cfound = False
        cval = None
        if isinstance(data, str) and self.__ignorecase(ignorecase):
            cdata = data.casefold()
            cconst = self.__casefolddict(constraint)
            if cdata in cconst:
                cfound = True
                cval = cconst[cdata]
            elif cdata in cconst.values():
                cfound = True
                cval = cdata
        else:
            if cdata in constraint:
                cfound = True
                cval = constraint[cdata]
            elif cdata in constraint.values():
                cfound = True
                cval = cdata
        validation = ValidationResult(
            cfound,
            EnumT,
            typedesc,
            constraint,
            cval if self.__forcecast(forcecast) else data,
            data,
            self.__forcecast(forcecast),
        )
        self.__storeresult(validation)
        return validation

    def raiseif(self):
        """Raises a DataValidationError iff at least one validation has failed."""
        if bool(self.failed):
            raise DataValidationError(self.tostring(errorsonly=True), self)

    def tohtml(self, errorsonly: bool = False):
        """Returns a paragraph-by-paragraph HTML representation of validation attempts.

        Args:
            errorsonly: Whether to include only the errors or all validation attempts.
        """
        if errorsonly:
            return "\n".join(
                [f'
{e.tohtml()}
' for e in self.failed]
            )
        return "\n".join([f'
{e.tohtml()}
' for e in self.results])

    def tostring(self, errorsonly: bool = False):
        """Returns a line-by-line string representation of validation attempts.

        Args:
            errorsonly: Whether to include only the errors or all validation attempts.
        """
        if errorsonly:
            return "\n".join([str(e) for e in self.failed])
        return "\n".join([str(e) for e in self.results])

    def __bool__(self):
        """Returns True if no validation errors have occured so far, False otherwise."""
        return bool(self.failed)

    def __str__(self):
        """Returns a line-by-line string representation of all validation attempts."""
        return self.tostring()

    def __repr__(self):
        """Returns a python-like representation of the (empty) validator object."""
        return f"{__class__}(forcecast={self.forcecast})"


from __future__ import print_function

import sys

from bddown_core import Pan
from util import bd_help

def show(links):
    if not len(links):
        bd_help('show')
    else:
        for url in links:
            pan = Pan()
            items = pan.get_file_infos(url)
            for info in items:
                print(u"{0}\n{1}\n\n".format(info.filename, info.dlink).encode('utf-8'))
    sys.exit(0)


from utils import *
import pickle
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedKFold

if __name__ == '__main__':
	# 读取word2v
	text_features = [
		[
			'data/sequence_text_user_id_{}.128d'.format(key),
			'sequence_text_user_id_{}'.format(key),
			128
		] for key in ['ad_id', 'creative_id', 'advertiser_id', 'product_id', 'industry', 'product_category', 'time', 'click_times']
	]
	args['text_features'] = text_features
	text_features_1 = [
		[
			'data/sequence_text_user_id_{}_fold.12d'.format(key),
			'sequence_text_user_id_{}_fold'.format(key),
			12
		] for key in ['creative_id', 'ad_id', 'product_id', 'advertiser_id', 'industry']
	]
	args['text_features_1'] = text_features_1

	# 字段w2v特征
	args['embeddings_tables'] = []
	for feature in args['text_features']:
		args['embeddings_tables'].append(pickle.load(open(feature[0], 'rb')))
	args['embeddings_tables_1'] = []
	# 字段kflod target encoding编码w2v特征
	for feature in args['text_features_1']:
		args['embeddings_tables_1'].append(pickle.load(open(feature[0], 'rb')))
	# user_id相关的统计特征
	dense_features = [
		'user_id_{}_{}'.format(a, b) for (a, b) in [
			('', 'size'), ('ad_id', 'unique'), ('creative_id', 'unique'), ('advertiser_id', 'unique'),
			('industry', 'unique'), ('product_id', 'unique'), ('time', 'unique'), ('click_times', 'sum'),
			('click_times', 'mean'), ('click_times', 'std')
		]
	]
	# 字段kflod target encoding特征
	for l in ['age_{}'.format(i) for i in range(10)] + ['gender_{}'.format(i) for i in range(2)]:
		for f in ['creative_id', 'ad_id', 'product_id', 'advertiser_id', 'industry']:
			dense_features.append('{}_{}_mean'.format(l, f))
	args['dense_features'] = dense_features

	# 设置参数
	args['n'] = 1
	args['text_dim'] = sum([feature[-1] for feature in text_features])
	args['pretrained_model_path'] = 'saved_models'
	args['vocab_dic'] = pickle.load(open(os.path.join(args['pretrained_model_path'], 'vocab.pkl'), 'rb'))
	args['text_dim_1'] = sum([feature[-1] for feature in text_features_1])
	args['vocab_dim_v1'] = 64
	args['hidden_size'] = 1024
	args['hidden_dropout_prob'] = 0.2
	args['out_size'] = len(args['dense_features']) + args['hidden_size'] * 2 + 1024 * args['n']
	args['linear_layer_size'] = [1024, 512]
	args['num_label'] = 20
	args['epoch'] = 10
	args['lr'] = 8e-5
	args['index'] = 0

	# 读取数据
	train_df = pd.read_pickle('data/train_user_features.pkl')
	test_df = pd.read_pickle('data/test_user_features.pkl')
	test_df['age'] = 1
	test_df['gender'] = 1
	train_df['label'] = train_df['age'] * 2 + train_df['gender']
	test_df['label'] = test_df['age'] * 2 + test_df['gender']
	df = train_df.append(test_df)
	ss = StandardScaler()
	ss.fit(df[args['dense_features']])
	train_df[args['dense_features']] = ss.transform(train_df[args['dense_features']])
	test_df[args['dense_features']] = ss.transform(test_df[args['dense_features']])
	test_dataset = TextDataset_Last(args, test_df)

	# 建立模型
	skf = StratifiedKFold(n_splits=10, random_state=10, shuffle=True)
	model = Ctr_Net(args)
	for i, (train_index, test_index) in enumerate(skf.split(train_df, train_df['label'])):
		if i == args['index']:
			train_dataset = TextDataset_Last(args, train_df.iloc[train_index])
			dev_dataset = TextDataset_Last(args, train_df.iloc[test_index])
			if os.path.exists(os.path.join(args['output_dir'], 'pytorch_model_age.bin')) and os.path.exists(os.path.join(args['output_dir'], 'pytorch_model_gender.bin')):
				pass
			else:
				model.train(train_dataset, dev_dataset)

	# 输出结果
	accs = []
	for label, num in [('age', 10), ['gender', 2]]:
		model.reload(label)
		if label == 'age':
			accs.append(model.evaluate(dev_dataset)[1])
			test_preds = model.evaluate(test_dataset)[4]
			test_df[label] = np.argmax(test_preds, axis=-1) + 1
		else:
			accs.append(model.evaluate(dev_dataset)[2])
			test_preds = model.evaluate(test_dataset)[5]
			test_df[label] = np.argmax(test_preds, axis=-1) + 1

	output_df = test_df[['user_id', 'age', 'gender']]
	output_df.to_csv(
		'submission_{}_{}.csv'.format(args['index'], round(sum(accs), 5)),
		index=False
	)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rospy
from sentry_kinematics_sim.msg import cmd_sentry
import sys, select, termios, tty
import pygame
import time
import math
msg = """
Control mrobot!
---------------------------
Moving around:
chassis:
   q    w    e
   a     s   d
yaw:
        i
    j   k   l

r/f : increase/decrease chassis speeds by 10%
t/g : increase/decrease yaw  speed by 10%
space key, k : force stop
anything else : stop smoothly

B to quit
"""

def getKey():
    tty.setraw(sys.stdin.fileno())
    rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
    if rlist:
        key = sys.stdin.read(1)
    else:
        key = ''
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    return key

def vels(speed,turn):
    return "currently:\tspeed %s\tturn %s " % (speed,turn)

def maxlimit(num,max):
    if num > max:
        num = max
    elif num < -max:
        num = -max
    return num

def set_vel(speed,k1,k2,add,_add):
    if k1:
        speed = speed + add
    if k2:
        speed = speed - add
    if (k1 == 0)&(k2 == 0):
        if speed > 0.3:
            speed = speed - _add
        elif speed < -0.3:
            speed = speed + _add
        else:
            speed = 0
    return speed

def rad_format(rad):
    if rad > math.pi:
        while rad > math.pi:
            rad = rad - 2 * math.pi
    elif rad < math.pi:
        while rad < -math.pi:
            rad = rad + math.pi
    return rad

def set_pos(pos,k1,k2,add):
    if k1:
        pos = pos + add
    if k2:
        pos = pos - add
    pos = rad_format(pos)
    return pos

def set_pos1(pos,k1,k2,add):
    if k1:
        pos = add*10
    if k2:
        pos = -add*5
    if k1==0&k2==0:
        pos = 0
    return pos

if __name__=="__main__":

    #settings = termios.tcgetattr(sys.stdin)
    rospy.init_node('sentry_cmd_key')
    pub = rospy.Publisher('/cmd_sentry', cmd_sentry, queue_size=5)
    chassis_max_speed = 0.5
    chassi_max_wz = 1
    yaw_max_speed = 2
    chassis_speed_add = 0.05

    yaw_pos_add = 0.005
    pitch_pos_add = 0.005
    speed_jian = 0.1

    vx = 0
    vy = 0
    wz = 0
    yaw = 0
    pitch = 0
    cmd_sentry_msg = cmd_sentry()
    cmd_key = ['q','w','e','a','s','d','r','f','t','g','i','j','k','l']
    pygame.init()
    pygame.display.set_mode((100,100))
    try:
        print(msg)
        while(1):
            keys = pygame.key.get_pressed()

            if keys[pygame.K_r]:
                yaw_pos_add = yaw_pos_add * 1.1
            if keys[pygame.K_f]:
                yaw_pos_add = yaw_pos_add * 0.9

            if keys[pygame.K_t]:
                chassis_speed_add = chassis_speed_add * 1.1
            if keys[pygame.K_g]:
                chassis_speed_add = chassis_speed_add * 0.9

            vx = set_vel(vx,keys[pygame.K_w],keys[pygame.K_s],chassis_speed_add,speed_jian)
            vy = set_vel(vy,keys[pygame.K_a],keys[pygame.K_d],chassis_speed_add,speed_jian)
            wz = set_vel(wz,keys[pygame.K_q],keys[pygame.K_e],chassis_speed_add,speed_jian)
            yaw = set_pos1(yaw,keys[pygame.K_j],keys[pygame.K_l],yaw_pos_add)
            pitch = set_pos(pitch,keys[pygame.K_i],keys[pygame.K_k],pitch_pos_add)
            # break
            if keys[pygame.K_b]:
                break
            vx = maxlimit(vx,chassis_max_speed)
            vy = maxlimit(vy,chassis_max_speed)
            wz = maxlimit(wz,chassi_max_wz)
            cmd_sentry_msg.vx = vx
            cmd_sentry_msg.vy = vy
            cmd_sentry_msg.wz = wz
            cmd_sentry_msg.pitch_add = pitch
            cmd_sentry_msg.yaw_add = yaw
            pub.publish(cmd_sentry_msg)

            pygame.event.pump()
            time.sleep(0.01)
    except Exception as e:
        print (e)


"""
This script contains functions used for input and output of GELATO.

## Inputs needed for GELATO

1) Input spectra (one FITS file per spectrum)

- The log10 of the wavelengths in Angstroms, column name: "loglam"
- The spectral flux density in flam units, column name: "flux"
- The inverse variances of the data points, column name: "ivar"
- saved in `gelato_input/spectra/`

2) Input list

- a comma delimited file (ending in .csv) where each object occupies a different line.
The first item in each line is the path to the spectrum.
The second is the redshift of the spectrum.

- a FITS table (ending in .fits) where each object occupies a different entry in the table.
The table must have the column "Path" for the path to the object,
and "z" containing the redshift of the object.

- saved in `gelato_input/catalogs/`

## Notes to keep in mind
- the DESI masked pixels have ivar=0 and flux=0 so we don't need to carry the mask itself

The script consists of following functions:
    1) gelatify_spectra(specprod, survey, program, healpix, targetids)
    2) create_path_column(table)
    3) gelatify(table, output_name)
    4) divide_into_subsamples(table, n_samp, output_root)
    5) gelato_output(output_name = 'GELATO-results.fits')
    6) get_gelato_columns(table, em_line, prop = 'Flux')
    7) velocities_to_wavelengths(v, lam_0)
    8) plot_image_gelato_ha(table, index, title = None, gdir = None)

Author : Ragadeepika
Version : 2022 November 7
"""

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

import numpy as np
import fitsio

from astropy.io import fits
from astropy.table import Table, Column, vstack
from astropy.modeling.models import Gaussian1D

from desispec import coaddition
from desispec.io import specprod_root, read_spectra

from glob import glob
import plotting_functions as pf

import matplotlib.pyplot as plt

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

## Making the matplotlib plots look nicer
settings = {
    'font.size':22,
    'axes.linewidth':2.0,
    'xtick.major.size':6.0,
    'xtick.minor.size':4.0,
    'xtick.major.width':2.0,
    'xtick.minor.width':1.5,
    'xtick.direction':'in',
    'xtick.minor.visible':True,
    'xtick.top':True,
    'ytick.major.size':6.0,
    'ytick.minor.size':4.0,
    'ytick.major.width':2.0,
    'ytick.minor.width':1.5,
    'ytick.direction':'in',
    'ytick.minor.visible':True,
    'ytick.right':True
}

plt.rcParams.update(**settings)

## Output files directories

## Path to spectra
spec_out = 'input/spectra'
## Path to catalogs
cat_out = 'input/catalogs'

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

def gelatify_spectra(specprod, survey, program, healpix, targetids):
    """
    Function to turn a given list of spectra into GELATO-input files.
    The input spectra files are saved in input/spectra folder.

    Parameters
    ----------
    specprod : str
        Spectral Release Name

    survey : str
        Survey name for the targetes. sv1|sv2|sv3|main|special

    program : str
        Observing program for the targets. dark|bright|other|backup

    healpix : int
        Healpix number for the targets

    targetids : numpy array
        Array of targetids in a given specprod, survey, program, and healpix

    Returns
    -------
    None.
        Saves the individual spectra in GELATO-required format.
    """

    # Root directory of DESI spectra for a given specprod
    specprod_dir = specprod_root(specprod)
    hpx_dir = f'{specprod_dir}/healpix'

    # Filename & directory
    coadd_filename = f'coadd-{survey}-{program}-{healpix}.fits'
    tgt_dir = f'{hpx_dir}/{survey}/{program}/{healpix//100}/{healpix}'

    # Using desispec to read the spectra
    coadd_obj = read_spectra(f'{tgt_dir}/{coadd_filename}')
    coadd_tgts = coadd_obj.target_ids().data

    sel = np.isin(coadd_tgts,targetids)
    coadd_obj_sel = coadd_obj[sel]
    coadd_sel_tgts = coadd_obj_sel.target_ids().data

    # Combined Spectra -
    spec_combined = coaddition.coadd_cameras(coadd_obj_sel)

    lam = spec_combined.wave['brz']
    loglam = np.log10(lam)

    # Loop over targetids
    for tgt in targetids:
        ## Find the index of each targetid
        ## Get flux and ivar values and write into a fits file
        i = (coadd_sel_tgts == tgt)
        flam = spec_combined.flux['brz'][i][0]
        flam_ivar = spec_combined.ivar['brz'][i][0]
        outfile = f'{spec_out}/gspec-{survey}-{program}-{healpix}-{tgt}.fits'
        fitsio.write(outfile,[loglam,flam,flam_ivar], names=['loglam','flux','ivar'], clobber=True)

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

def create_path_column(table):
    """
    Function to create the "Path" column for the GELATO input file.

    Parameters
    ----------
    table : astropy table
        Table of sources that needs to be "gelatified"

    Returns
    -------
    path_column : Column
        "Path" column containing the path to the different input spectra

    """

    ## Each spectrum filename - input/spectra/gspec-{survey}-{program}-{healpix}-{targetid}.fits

    survey = table['SURVEY'].astype(str).data.astype(object)
    program = table['PROGRAM'].astype(str).data.astype(object)
    healpix = table['HEALPIX'].astype(str).data.astype(object)
    targetid = table['TARGETID'].astype(str).data.astype(object)
    spec_out = np.array(['input/spectra/gspec-']*len(table)).astype(object)
    hyphen = np.array(['-']*len(table)).astype(object)
    fits = np.array(['.fits']*len(table)).astype(object)

    path = spec_out+survey+hyphen+program+hyphen+healpix+hyphen+targetid+fits
    path_column = Column(path, name = 'Path', dtype = 'str')

    return (path_column)

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

def gelatify(table, output_name):
    """
    Function to create the required GELATO input files for a given table of targets.

    Parameters
    ----------
    table : astropy table
        Table of sources that needs to be "gelatified"

    output_name : str
        Name of the output catalog

    Returns
    -------
    None.
        The output catalog is saved with the given name in input/catalogs/ folder.
    """

    specprods = np.unique(table['SPECPROD'].astype(str))
    ## group by specprod
    for specprod in specprods:
        t_spec = table[table['SPECPROD'].astype(str) == specprod]

        ## group by survey
        surveys = np.unique(t_spec['SURVEY'].astype(str))
        for survey in surveys:
            t_surv = t_spec[t_spec['SURVEY'].astype(str) == survey]

            ## group by program
            programs = np.unique(t_spec['PROGRAM'].astype(str))
            for program in programs:
                t_prog = t_surv[t_surv['PROGRAM'].astype(str) == program]

                ## group by healpix
                healpixs = np.unique(t_prog['HEALPIX'])
                for hpx in healpixs:
                    t_hpx = t_prog[t_prog['HEALPIX'] == hpx]
                    tgts = t_hpx['TARGETID'].data
                    gelatify_spectra(specprod, survey, program, hpx, tgts)

    print (' ')
    print ('Done!')

    ## Create the GELATO input list with 'Path' and 'z'
    ## Initialize output table
    t_out = Table()
    path_col = create_path_column(table)
    t_out.add_column(path_col)
    t_out['z'] = table['Z']
    t_out.write(f'{cat_out}/{output_name}', overwrite = True)

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

def divide_into_subsamples(table, n_samp, output_root):
    """
    Function to divide the entire catalog into sub-samples to help with GELATO run.

    Parameters
    ----------
    table : astropy table
        GELATO input table that needs to be divided into sub-samples

    n_samp : int
        Number of sub-samples

    output_root : str
        Output root name for each of the sub-samples.

    Returns
    -------
    None.
        The tables for all the sub-samples are saved in input/catalogs/ folder.

    """

    for ii in range(n_samp):
        tab = table[ii::n_samp]
        tab.write(f'{cat_out}/{outpit_root}-{ii+1}.fits', overwrite = True)

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

def gelato_output(output_name = 'GELATO-results.fits'):
    """
    Function to combine all GELATO output files to get a single results file.
    The files should reside in Results/ folder.

    Parameters
    ----------
    output_name : str
        Path and filename for the resulting file. Default in GELATO-results.fits

    Returns
    -------
    None.
        The output file is saved at the required path.

    """

    files = glob('Results/gspec*.fits')

    tables = []

    for ii in range(len(files)):
        comps = files[ii][8:].split('-')
        filename = '-'.join(comps[:-1])+'.fits'
        targetid = comps[-2]
        parameters = fits.getdata(files[ii], 'PARAMS')

        ## Initialize Lists
        data = [targetid, filename]
        names = ['TARGETID', 'Name']
        dtype = ['>i8', np.unicode_] + [np.float64 for i in range(2*len(parameters.columns.names))]

        # Iterate over columns and add
        for n in parameters.columns.names:

            ps = parameters[n]
            ps = ps[np.invert(np.isinf(ps))]

            # Add medians
            data.append(np.nanmedian(ps))
            names.append(n)

            # Add errors
            data.append(np.nanstd(ps))
            names.append(n+'_err')

        # Append to list
        tables.append(Table(data=np.array(data),names=names,dtype = dtype))

    table = vstack(tables, join_type = 'outer')
    #if not type(table.mask) == type(None):
    #    for c in table.colnames[1:]: table[c][table.mask[c]] = np.nan

    table.write(output_name, overwrite = True)

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

def get_gelato_columns(table, em_line, prop = 'Flux'):
    """
    Function to output GELATO columns for a given emission line.

    Parameters
    ----------
    table : astropy table
        GELATO results table from which to grab the required columns

    em_line : str
        Required emission-line.
        For now works only for Ha, Hb, [NII], [OIII], [SII]_6716/6731, 'Ha_broad', 'Hb_broad'.

    prop : str
        Property name whose column needs to be grabbed for the given emission line.
        Default is 'Flux'

    Returns
    -------
    column : Column
        Required emission-line column.

    """
    ## Dictionary to match emission-line with the required column
    gel_dict = {'Ha':'BPT_Ha_6564.613',
                'Hb':'BPT_Hb_4862.683',
                '[NII]':'BPT_[NII]_6585.277',
                '[OIII]':'BPT_[OIII]_5008.239',
                '[SII]_6716':'BPT_[SII]_6718.294',
                '[SII]_6731':'BPT_[SII]_6732.673',
                'Ha_broad':'Broad_Ha_Broad_6564.613',
                'Hb_broad':'Broad_Hb_Broad_4862.683'}

    term = gel_dict[em_line]
    column_name = f'{term}_{prop}'
    column = table[column_name].data

    return (column)

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

def velocities_to_wavelengths(v, lam_0):
    """
    Function to convert from velocities (km/s) to wavelength values (in AA).
    del_lam = (v/c)*lam_0

    Parameters
    ----------
    v : array or float
        Velocities that need to be converted

    lam_0 : float
        Central wavelength for the frame of reference

    Returns
    -------
    del_lam : array or float
        Converted wavelength values
    """

    c = 3e+5 ## in km/s
    del_lam = (v/c)*lam_0

    return (del_lam)

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

def plot_image_gelato_ha(table, index, title = None, gdir = None):
    """
    Function to plot image-cutout and spectra+gelato model focused on the Ha+[NII] region.
    This function overplots the broad and narrow components of Ha.

    Parameters
    ----------
    table : astropy table
        The table of targets from which the object is selected.

    index : int
        Index of the object from the table that needs to be plotted.

    title : str
        Title that will go on the top of the plot. Default is None.

    gdir : str
        Path of the gelato output results files. Default is None.

    Returns
    -------
    fig : matplotlib figure
        Figure object containing the overall plot
    """
    ## Target information
    filename = table['Name'].astype(str).data[index]
    arr = filename.split('.')
    #targetid = table['TARGETID'].data[index]
    ra = table['RA'].data[index]
    dec = table['DEC'].data[index]

    gtab_file = f'{gdir}/{arr[0]}-results.fits'
    gtab = Table.read(gtab_file, hdu = 1)

    for c in gtab.columns:
        gtab[c].fill = 0.0

    gtab = gtab.filled()

    #c = 3e+5  ## in km/s
    #z = table['SSP_Redshift'].data[index]/c
    z = table['Z'].data[index]
    ## Spectra
    lam = 10**(gtab['loglam'])/(1+z)
    flam = gtab['flux']*(1+z)
    ivar = gtab['ivar']/((1+z)**2)

    model = gtab['MODEL']*(1+z)
    if ('PL' in gtab.colnames):
        cont = (gtab['SSP']+gtab['PL'])*(1+z)
    else:
        cont = gtab['SSP']*(1+z)
    residual = model - flam

    ## Gaussian components for Broad and Narow Halpha
    ha_mean = 6564.613

    ## Narrow H-alpha

    ha_amp = get_gelato_columns(table, 'Ha', prop = 'RAmp')[index]
    ha_sig = get_gelato_columns(table, 'Ha', prop = 'Dispersion')[index]

    ha_std = velocities_to_wavelengths(ha_sig, ha_mean)

    gauss_ha = Gaussian1D(amplitude = ha_amp, mean = ha_mean, stddev = ha_std)

    ## Broad H-alpha

    ha_broad_amp = get_gelato_columns(table, 'Ha_broad', prop = 'RAmp')[index]
    ha_broad_sig = get_gelato_columns(table, 'Ha_broad', prop = 'Dispersion')[index]
    ha_broad_std = velocities_to_wavelengths(ha_broad_sig, ha_mean)

    gauss_ha_broad = Gaussian1D(amplitude = ha_broad_amp, mean = ha_mean, stddev = ha_broad_std)

    ## Get image-cutout
    im = pf.get_image_cutout(ra_in = ra, dec_in = dec, cutout_size = 20)

    ## Region around [NII]+Ha
    lam_xx = np.arange(6400, 6700, 1)
    lam_ii = (lam >= 6400)&(lam <= 6700)
    cont_xx = np.median(cont[lam_ii])

    ## Plot

    fig = plt.figure(figsize = (14, 12))
    gs = fig.add_gridspec(6, 5)

    plt.suptitle(title, fontsize = 20)

    ax1 = fig.add_subplot(gs[0:2,0:2])
    ax2 = fig.add_subplot(gs[0:2,2:])
    ax3 = fig.add_subplot(gs[2:5,:])
    ax4 = fig.add_subplot(gs[5,:], sharex = ax3)

    ax1.imshow(im)
    ax1.set(xticks = [], yticks = [])

    ax2.plot(lam, flam, color = 'grey', alpha = 0.8, label = 'Flux')
    ax2.plot(lam_xx, gauss_ha(lam_xx)+cont_xx, color = 'r', label = 'Narrow H$\\alpha$')
    ax2.plot(lam_xx, gauss_ha_broad(lam_xx)+cont_xx, color = 'b', label = 'Broad H$\\alpha$')
    ax2.legend(loc = 'best', fontsize = 12)
    ax2.set(ylabel = '$F_{\lambda}$', xlim = [6440, 6680], xlabel = '$\lambda$')

    x_bounds = ax2.get_xbound()
    x_ii = (lam >= x_bounds[0])&(lam <= x_bounds[1])
    flam_ii = flam[x_ii]
    ymin_ii = min(flam_ii)-1
    ymax_ii = max(flam_ii)+1
    ax2.set_ylim([ymin_ii, ymax_ii])

    ax3.plot(lam, flam, color = 'grey', alpha = 0.8, label = 'Flux')
    ax3.plot(lam, model, color = 'k', lw = 2.0, label = 'Model')
    ax3.legend(loc = 'best', fontsize = 16)
    ax3.set(ylabel = '$F_{\lambda}$', xlim = [4600, 6900])

    x_bounds = ax3.get_xbound()
    x_ii = (lam >= x_bounds[0])&(lam <= x_bounds[1])
    flam_ii = flam[x_ii]
    ymin_ii = min(flam_ii)-1
    ymax_ii = max(flam_ii)+1
    ax3.set_ylim([ymin_ii, ymax_ii])

    ax4.scatter(lam, residual, color = 'k', s = 10, marker = '.', alpha = 0.5)
    ax4.axhline(0.0, color = 'firebrick', ls = '--', lw = 3.0)
    ax4.set_ylabel('Residual', fontsize = 16)
    ax4.set(ylim = [-7,7], xlabel = '$\lambda$')

    plt.tight_layout(rect=[0, 0, 1., 0.99])
    plt.close()

    return (fig)

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


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 15 22:02:03 2019

@author: hanpeng
"""

def fifthPower(n):
    return sum([int(i)**5 for i in str(n)])

def digitFifthPower():

    upperBound = 9**5*6
    total = 0
    while upperBound > 2:
        if upperBound == fifthPower(upperBound):
            total += upperBound

        upperBound -= 1

    return total

print(digitFifthPower())


#Write a Python program to convert a given camel case string to snake case.
import re
snake7 = str(input())

temp1 = snake7.split(' ')

camel7 ='_'.join(i.title() for i in temp1)

print(camel7)