from typing import Optional, Tuple, Union
import gc

import torch
from torch import nn
from torch.utils.checkpoint import checkpoint
from torch.nn import CrossEntropyLoss
from transformers.configuration_utils import PretrainedConfig
from transformers.modeling_outputs import (
    BaseModelOutputWithPast,
    CausalLMOutputWithPast,
)
from transformers.modeling_utils import PreTrainedModel

# from transformers.utils import logging
import logging

from optimus.model.init_functions import get_init_methods
from optimus.model.norms import get_norm
from optimus.model.utils import get_fusion_type
from optimus.model.transformer import ParallelLinear, ParallelTransformerLayer
from optimus.model.word_embeddings import Embedding
from optimus.model.fused_softmax import FusedScaleMaskSoftmax
from optimus.generator.generator import Generator
import optimus.mpu as mpu
from functools import partial
import optimus.model.init_functions as init

""" llama model configuration"""

# logger = logging.get_logger(__name__)

# We use huggingface config as the pesudo `neox_args` to create megatron model of GPTNeoX
class LlamaConfig(PretrainedConfig):
    r"""
    This is the configuration class to store the configuration of a [`LlamaModel`]. It is used to instantiate an
    LLama model according to the specified arguments, defining the model architecture. Instantiating a configuration

    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
    documentation from [`PretrainedConfig`] for more information.

    Args:
        vocab_size (`int`, *optional*, defaults to 50432):
            Vocabulary size of the LLama model. Defines the number of different tokens that can be represented by the
            `inputs_ids` passed when calling [`LlamaModel`].
        hidden_size (`int`, *optional*, defaults to 6144):
            Dimension of the encoder layers and the pooler layer.
        num_hidden_layers (`int`, *optional*, defaults to 44):
            Number of hidden layers in the Transformer encoder.
        num_attention_heads (`int`, *optional*, defaults to 64):
            Number of attention heads for each attention layer in the Transformer encoder.
        intermediate_size (`int`, *optional*, defaults to 24576):
            Dimension of the "intermediate" (i.e., feed-forward) layer in the Transformer encoder.
        hidden_act (`str` or `function`, *optional*, defaults to `"gelu"`):
            The non-linear activation function (function or string) in the encoder and pooler. If string, `"gelu"`,
            `"relu"`, `"selu"` and `"gelu_new"` are supported.
        rotary_pct (`float`, *optional*, defaults to 0.25):
            percentage of hidden dimensions to allocate to rotary embeddings
        rotary_emb_base (`int`, *optional*, defaults to 10000)
            base for computing rotary embeddings frequency
        max_position_embeddings (`int`, *optional*, defaults to 2048):
            The maximum sequence length that this model might ever be used with. Typically set this to something large
            just in case (e.g., 512 or 1024 or 2048).
        initializer_range (`float`, *optional*, defaults to 1e-5):
            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
        layer_norm_eps (`float`, *optional*, defaults to 1e-12):
            The epsilon used by the layer normalization layers.
        use_cache (`bool`, *optional*, defaults to `True`):
            Whether or not the model should return the last key/values attentions (not used by all models). Only
            relevant if `config.is_decoder=True`.
        use_parallel_residual (`bool`, *optional*, defaults to `True`):
            Whether to use a "parallel" formulation in each Transformer layer, which can provide a slight training
            speedup at large scales (e.g. 20B).
    """
    model_type = "llama"

    def __init__(
        self,
        vocab_size=32000,
        hidden_size=4096,
        num_hidden_layers=32,
        num_attention_heads=32,
        intermediate_size=11008,
        hidden_act="silu",
        rotary_pct=1,
        rotary_emb_base=10000,
        max_position_embeddings=2048,
        initializer_range=0.02,
        rms_norm_epsilon=1.0e-6,
        use_cache=True,
        pad_token_id=0,
        bos_token_id=1,
        eos_token_id=2,
        tie_word_embeddings=False,
        use_parallel_residual=True,
        **kwargs,
    ):
        self.vocab_size = vocab_size
        self.max_position_embeddings = max_position_embeddings
        self.hidden_size = hidden_size
        self.num_hidden_layers = num_hidden_layers
        self.num_attention_heads = num_attention_heads
        self.intermediate_size = intermediate_size
        self.hidden_act = hidden_act
        self.rotary_pct = rotary_pct
        self.rotary_emb_base = rotary_emb_base
        self.initializer_range = initializer_range
        self.rms_norm_epsilon = rms_norm_epsilon
        self.use_cache = use_cache
        self.tie_word_embeddings = tie_word_embeddings
        self.use_parallel_residual = use_parallel_residual
        super().__init__(
            pad_token_id=pad_token_id,
            bos_token_id=bos_token_id,
            eos_token_id=eos_token_id,
            tie_word_embeddings=tie_word_embeddings,
            **kwargs,
        )
        self.init_epilogue()

    def init_epilogue(self):
        self.num_layers = self.num_hidden_layers
        self.use_mup = False
        self.use_cpu_initialization = False
        self.opt_pos_emb_offset = False
        self.activation = getattr(self, "hidden_act", "silu")
        self.padded_vocab_size = self.vocab_size
        self.precision = "fp16" if self.torch_dtype == "float16" else "bfloat16"
        self.use_flash_attention = True
        self.use_cache = True

        self.isGQA = getattr(self, "isGQA", False)

    @property
    def params_dtype(self):
        return torch.float16 if self.precision == "fp16" else torch.bfloat16

    def __getattr__(self, name):
        if "mup" in name or "bnb" in name:
            return None  # disable mup & bnb for now
        else:
            return object.__getattribute__(self, name)

def expand_attention_types(attention_config, num_layers):
    """
    Expands an `attention_config` list in the following format:

        [
        [['attention_type_1', ..., `attention_type_n`], 12]
        ]

    to a flattened list of length `num_layers`.

    :param params_list:
    :return:
    """
    # if only strings are found in the config, we assume it's already expanded
    if all([isinstance(i, str) for i in attention_config]):
        return attention_config
    newlist = []
    for item in attention_config:
        # instead of specifying a number - we can specify 'all' to extend this pattern across all layers
        if item[1] == "all":
            assert num_layers % len(item[0]) == 0, (
                f"Number of layers ({num_layers}) is not divisible by the length "
                f"of pattern: {item[0]}"
            )
            return item[0] * (num_layers // len(item[0]))
        for _ in range(item[1]):
            newlist.extend(item[0])
    return newlist

def gpt2_attention_mask_func(attention_scores, ltor_mask):
    attention_scores.masked_fill_(ltor_mask, torch.finfo(attention_scores.dtype).min)
    return attention_scores

class LlamaPreTrainedModel(PreTrainedModel):
    """
    An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained
    models.
    """

    config_class = LlamaConfig
    base_model_prefix = "llama"
    supports_gradient_checkpointing = True
    _no_split_modules = ["LLamaLayer"]

    def _init_weights(self, module):
        """Initialize the weights"""
        pass

    def _set_gradient_checkpointing(self, module, value=False):
        if isinstance(module, LlamaPreTrainedModel):
            module.gradient_checkpointing = value

class LlamaModel(LlamaPreTrainedModel):
    def __init__(self, config):
        super().__init__(config)
        config.attention_config = expand_attention_types(
            config.attention_config, config.num_hidden_layers
        )
        is_rotary = config.pos_emb == "rotary"
        self.config = config
        self.init_method, self.output_layer_init_method = get_init_methods(config)
        self.embed_in = Embedding(
            config,
            config.hidden_size,
            config.vocab_size,
            config.max_position_embeddings,
            config.hidden_dropout,
            self.init_method,
            num_tokentypes=0,
        )
        self.layers = nn.ModuleList(
            [
                ParallelTransformerLayer(
                    config,
                    attention_mask_func=gpt2_attention_mask_func,
                    init_method=self.init_method,
                    output_layer_init_method=self.output_layer_init_method,
                    layer_number=i,
                    rpe=None,
                    rotary=is_rotary,
                    use_cache=config.use_cache,
                )
                for i in range(config.num_hidden_layers)
            ]
        )
        norm, eps = get_norm(config)
        self.final_layer_norm = norm(config.hidden_size, eps=eps)

        self.gradient_checkpointing = True

        # in each of transformer layers, we have a fused softmax

        self.post_init()

        self.kv_enabled(config.use_cache)

    def get_input_embeddings(self):
        return self.embed_in

    def set_input_embeddings(self, value):
        self.embed_in = value

    def fmha_enabled(self, use_fmha):
        for layer in self.layers:
            layer.attention.use_flash_attention = use_fmha

    def kv_enabled(self, use_cache):
        if use_cache is None:
            use_cache = False

        for layer in self.layers:
            layer.use_cache = use_cache
            layer.attention.use_cache = use_cache

            # disable flash attention if cache is enabled
            # use_fmha = layer.attention.use_flash_attention
            # layer.attention.use_flash_attention = (not use_cache) and use_fmha

        self.use_cache = use_cache
        # self.gradient_checkpointing = not use_cache

    def checkpointing_enabled(self, c: bool):
        self.gradient_checkpointing = c  # done in kv_enabled

    def forward(
        self,
        input_ids: Optional[torch.LongTensor] = None,
        attention_mask: Optional[torch.FloatTensor] = None,
        position_ids: Optional[torch.LongTensor] = None,
        past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
        left_padding: Optional[bool] = False,
    ) -> Union[Tuple, BaseModelOutputWithPast]:
        r"""
        past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`):
            Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding.
            If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
            don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
            `decoder_input_ids` of shape `(batch_size, sequence_length)`.
        use_cache (`bool`, *optional*):
            If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
            `past_key_values`).
        """

        if use_cache is None:
            use_cache = False

        if self.use_cache != use_cache:
            self.kv_enabled(use_cache)
        use_cache = self.use_cache

        output_attentions = (
            output_attentions
            if output_attentions is not None
            else self.config.output_attentions
        )
        output_hidden_states = (
            output_hidden_states
            if output_hidden_states is not None
            else self.config.output_hidden_states
        )
        return_dict = (
            return_dict if return_dict is not None else self.config.use_return_dict
        )
        use_cache = use_cache if use_cache is not None else self.config.use_cache

        batch_size, seq_length = input_ids.size()

        if past_key_values is None:
            past_length = 0
            past_key_values = [None] * self.config.num_hidden_layers
        else:
            past_length = past_key_values[0][0].size(0)

        # presents = past_key_values if use_cache else None

        if position_ids is None:
            position_ids = torch.arange(
                past_length,
                seq_length + past_length,
                dtype=torch.long,
                device=input_ids.device,
            )
            position_ids = position_ids.unsqueeze(0).view(-1, seq_length)
        else:
            position_ids = position_ids.view(-1, seq_length).long()

        # Attention mask.
        if left_padding:
            non_causal_attention_mask = attention_mask.clone()
            position_ids_in = position_ids.clone()
        else:
            non_causal_attention_mask = None
            position_ids_in = None

        if attention_mask is not None:
            assert batch_size > 0, "batch_size has to be defined and > 0"
            attention_mask = attention_mask.view(batch_size, -1)
            attention_mask = attention_mask[:, None, None, :]
            tril_mask = torch.tril(
                torch.ones((1, seq_length, seq_length), device=attention_mask.device)
            ).view(1, 1, seq_length, seq_length)
            attention_mask = attention_mask * tril_mask
            attention_mask = attention_mask < 0.5

        hidden_states = self.embed_in(input_ids, position_ids=position_ids)
        hidden_states = hidden_states.transpose(0, 1).contiguous()
        all_attentions = () if output_attentions else None
        all_hidden_states = () if output_hidden_states else None

        # for _, (layer, layer_past) in enumerate(zip(self.layers, past_key_values)):
        for i in range(self.config.num_hidden_layers):
            layer = self.layers[i]
            if output_hidden_states:
                all_hidden_states = all_hidden_states + (hidden_states,)

            if self.gradient_checkpointing:
                # when use grad checkpoint, we don't use cache, then
                # we dont need left padding, use ROPE New version
                hidden_states = checkpoint(layer, hidden_states, attention_mask)
            else:
                # use cache should close grad checkpoint
                # we use position_ids when use cache and left padding
                # use ROPE old version
                out = layer(
                    hidden_states,
                    attention_mask=attention_mask,
                    layer_past=past_key_values[i],
                    non_causal_attention_mask=non_causal_attention_mask,
                    position_ids=position_ids_in,
                )
                if self.use_cache:
                    hidden_states, cache = out
                    past_key_values[i] = cache
                else:
                    hidden_states = out

            if output_attentions:
                all_attentions = all_attentions + (layer.layer_past,)

        hidden_states = hidden_states.transpose(0, 1).contiguous()
        hidden_states = self.final_layer_norm(hidden_states)
        # Add last hidden state
        if output_hidden_states:
            all_hidden_states = all_hidden_states + (hidden_states,)

        if not return_dict:
            return tuple(
                v
                for v in [hidden_states, all_hidden_states, all_attentions]
                if v is not None
            )

        return BaseModelOutputWithPast(
            last_hidden_state=hidden_states,
            hidden_states=all_hidden_states,
            past_key_values=past_key_values if self.use_cache else None,
            attentions=all_attentions,
        )

    def resize_token_embeddings(self, new_num_tokens: Optional[int] = None):
        old_vocab_size = self.config.vocab_size
        self.config.vocab_size = new_num_tokens
        new_embed_in = Embedding(
            self.config,
            self.config.hidden_size,
            self.config.vocab_size,
            self.config.max_position_embeddings,
            self.config.hidden_dropout,
            self.init_method,
            num_tokentypes=0,
        )
        new_embed_in.word_embeddings.weight.data[
            :old_vocab_size, :
        ] = self.embed_in.word_embeddings.weight.data[:old_vocab_size, :]

        self.embed_in = new_embed_in
        return

class LlamaForCausalLM(LlamaPreTrainedModel):
    def __init__(self, config):
        super().__init__(config)

        self.llama = LlamaModel(config)
        self.init_method, self.output_layer_init_method = get_init_methods(config)
        self.embed_out = ParallelLinear(
            self.config,
            init_method=self.init_method,
            parallel_output=False,
        )

        # Initialize weights and apply final processing
        self.post_init()

    def get_output_embeddings(self):
        return self.embed_out

    def set_output_embeddings(self, new_embeddings):
        self.embed_out = new_embeddings

    def forward(
        self,
        input_ids: Optional[torch.LongTensor] = None,
        attention_mask: Optional[torch.LongTensor] = None,
        position_ids: Optional[torch.LongTensor] = None,
        past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
        left_padding=False,
        compute_lm_loss: Optional[bool] = False,
        labels: Optional[torch.LongTensor] = None,
    ) -> Union[Tuple, CausalLMOutputWithPast]:
        r"""
        past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
            Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape
            `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape
            `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. The two additional tensors are
            only required when the model is used as a decoder in a Sequence to Sequence model.

            Contains pre-computed hidden-states (key and values in the self-attention blocks that can be used (see
            `past_key_values` input) to speed up sequential decoding.

            If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
            don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
            `decoder_input_ids` of shape `(batch_size, sequence_length)`.
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the left-to-right language modeling loss (next word prediction). Indices should be in
            `[-100, 0, ..., config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are
            ignored (masked), the loss is only computed for the tokens with labels n `[0, ..., config.vocab_size]`.
        use_cache (`bool`, *optional*):
            If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
            `past_key_values`).

        Returns:

        """
        return_dict = (
            return_dict if return_dict is not None else self.config.use_return_dict
        )

        batch_size, seq_length = input_ids.size()
        if attention_mask is None:
            attention_mask = input_ids.new_ones(input_ids.shape)

        if attention_mask is not None and position_ids is None:
            # create position_ids on the fly for batch generation
            position_ids = attention_mask.long().cumsum(-1) - 1
            position_ids.masked_fill_(attention_mask == 0, 1)

        # if left_padding:
        #     logging.debug("left padding enbled")

        outputs = self.llama(
            input_ids,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_values=past_key_values,
            use_cache=use_cache,
            output_attentions=output_attentions,
            output_hidden_states=output_hidden_states,
            return_dict=return_dict,
            left_padding=left_padding,
        )

        hidden_states = outputs[0]
        lm_logits = self.embed_out(hidden_states)[0]
        lm_loss = None

        if labels is not None and compute_lm_loss:
            # we are doing next-token prediction; shift prediction scores and input ids by one
            shift_logits = lm_logits[:, :-1, :].contiguous()
            labels = labels[:, 1:].contiguous()
            loss_fct = CrossEntropyLoss(reduction="none")
            lm_loss = loss_fct(
                shift_logits.view(-1, shift_logits.size(-1)), labels.view(-1)
            )
            # loss_weight = loss_weight[:, 1:].contiguous().view(-1)
            # lm_loss = (lm_loss * loss_weight).sum() / loss_weight.sum()
            lm_loss = lm_loss.mean()

        if not return_dict:
            output = (lm_logits,) + outputs[1:]
            return ((lm_loss,) + output) if lm_loss is not None else output

        return CausalLMOutputWithPast(
            loss=lm_loss,
            logits=lm_logits,
            past_key_values=outputs.past_key_values,
            hidden_states=outputs.hidden_states,
            attentions=outputs.attentions,
        )

    def prepare_inputs_for_generation(
        self, input_ids, past_key_values=None, attention_mask=None, **kwargs
    ):
        if past_key_values and past_key_values[0] is not None:
            input_ids = input_ids[:, -1:]

        position_ids = kwargs.get("position_ids", None)
        if attention_mask is not None and position_ids is None:
            # create position_ids on the fly for batch generation
            position_ids = attention_mask.long().cumsum(-1) - 1
            position_ids.masked_fill_(attention_mask == 0, 1)
            if past_key_values:
                position_ids = position_ids[:, -1].unsqueeze(-1)

        # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
        if attention_mask is None:
            attention_mask = input_ids.new_ones(input_ids.shape)

        return {
            "input_ids": input_ids,
            "attention_mask": attention_mask,
            "position_ids": position_ids,
            "past_key_values": past_key_values,
            **kwargs,
        }

    def _reorder_cache(self, past_key_values, beam_idx):
        reordered_past = ()
        for layer_past in past_key_values:
            reordered_past += (
                tuple(
                    past_state.index_select(0, beam_idx)
                    for past_state in layer_past[:2]
                )
                + layer_past[2:],
            )
        return reordered_past

    def resize_token_embeddings(self, new_num_tokens: Optional[int] = None):
        self.llama.resize_token_embeddings(new_num_tokens)
        old_vocab_size = self.config.vocab_size
        new_embed_out = ParallelLinear(
            config=self.config, init_method=self.init_method, parallel_output=False
        )
        new_embed_out.final_linear.weight.data[
            :old_vocab_size, :
        ] = self.embed_out.final_linear.weight.data[:old_vocab_size, :]
        self.embed_out = new_embed_out
        return

class LlamaForRM(LlamaPreTrainedModel):
    def __init__(self, config):
        super().__init__(config)

        self.config = config
        self.llama = LlamaModel(config)
        logging.info(f"LlamaModel loaded, {config.params_dtype}")
        self.value_head = mpu.ColumnParallelLinear(
            config,
            config.hidden_size,
            mpu.get_model_parallel_world_size(),
            bias=False,
            gather_output=True,
        )

        self.llama.kv_enabled(False)
        self.llama.fmha_enabled(True)

        # Initialize weights and apply final processing
        self.post_init()

        self.bce_loss = nn.BCEWithLogitsLoss()
        self.need_value_dropout = False
        if hasattr(config, "value_dropout") and config.value_dropout > 0:
            from optimus.hf.model_utils import StableDropout

            p = config.value_dropout
            self.value_dropout = StableDropout(p)
            self.need_value_dropout = True

    def forward(
        self,
        input_ids: Optional[torch.LongTensor] = None,
        attention_mask: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.LongTensor] = None,
        past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
        compute_loss_c1r1: Optional[bool] = False,
        compute_loss_c1r2: Optional[bool] = False,
        compute_loss_c1r4: Optional[bool] = False,
        compute_loss_for_sentence_classification: Optional[bool] = False,
        compute_softmax_c1r4: Optional[bool] = False,
        compute_loss_c1r4_new: Optional[bool] = False,
        labels: Optional[torch.LongTensor] = None,
    ) -> Union[Tuple, CausalLMOutputWithPast]:
        r"""
        past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
            Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape
            `(batch_size, num_heads, sequence_length, embed_size_per_head)`) and 2 additional tensors of shape
            `(batch_size, num_heads, encoder_sequence_length, embed_size_per_head)`. The two additional tensors are
            only required when the model is used as a decoder in a Sequence to Sequence model.

            Contains pre-computed hidden-states (key and values in the self-attention blocks that can be used (see
            `past_key_values` input) to speed up sequential decoding.

            If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that
            don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all
            `decoder_input_ids` of shape `(batch_size, sequence_length)`.
        labels (`torch.LongTensor` of shape `(batch_size, )`):
            Labels gives the length of each group of rewards.
        use_cache (`bool`, *optional*):
            If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
            `past_key_values`).

        Returns:

        """
        return_dict = (
            return_dict if return_dict is not None else self.config.use_return_dict
        )

        # if model is used as a decoder in encoder-decoder model, the decoder attention mask is created on the fly
        if attention_mask is None:
            attention_mask = input_ids.new_ones(input_ids.shape)

        if position_ids is None:
            # Position ids.
            batch_size, seq_length = input_ids.size()
            # position_ids = torch.arange(
            #     seq_length, dtype=torch.long, device=input_ids.device
            # )
            # position_ids = position_ids.unsqueeze(0).expand_as(input_ids)

            position_ids = attention_mask.long().cumsum(-1) - 1
            position_ids.masked_fill_(attention_mask == 0, 1)
            position_ids = position_ids.view(-1, seq_length).long()

        outputs = self.llama(
            input_ids,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_values=past_key_values,
            use_cache=use_cache,
            output_attentions=output_attentions,
            output_hidden_states=output_hidden_states,
            return_dict=return_dict,
        )

        last_hidden_states = outputs[0]
        last_index = attention_mask.cumsum(dim=1).argmax(dim=1)
        last_hidden_states = last_hidden_states.gather(
            1, last_index.view(-1, 1, 1).expand(-1, 1, last_hidden_states.size(-1))
        ).squeeze(1)
        if self.need_value_dropout:
            last_hidden_states = self.value_dropout(last_hidden_states)
        values = self.value_head(last_hidden_states)[0]  # (bs, world_size)
        values = values.mean(dim=1) # (bs,)

        if compute_loss_for_sentence_classification:
            loss = self.bce_loss(values.float(), labels.float())
            return loss

        if compute_loss_c1r1:
            # first half is chosen, the other is rejected, by order
            total_batch_size = input_ids.size(0)
            assert total_batch_size % 2 == 0 and total_batch_size == len(values)
            values = values.float()
            chosen = values[: total_batch_size // 2]
            rejected = values[total_batch_size // 2 :]
            loss = -torch.nn.functional.logsigmoid(chosen - rejected).mean()
            return loss

        if compute_loss_c1r2:
            total_batch_size = input_ids.size(0)
            assert total_batch_size % 3 == 0 and total_batch_size == len(values)
            values = values.float()
            chosen = values[: total_batch_size // 3]
            reject1 = values[total_batch_size // 3 : 2 * total_batch_size // 3]
            reject2 = values[2 * total_batch_size // 3 :]
            # loss = -torch.nn.functional.logsigmoid(2 * chosen - reject1 - reject2).mean()
            loss = (
                -torch.nn.functional.logsigmoid(chosen - reject1)
                - torch.nn.functional.logsigmoid(chosen - reject2)
            ).mean()
            return loss

        if compute_softmax_c1r4:
            total_batch_size = input_ids.size(0)
            assert total_batch_size % 5 == 0 and total_batch_size == len(values)
            values = values.float()
            num_sample = total_batch_size // 5

            values = values.view(5, num_sample)
            values = values.transpose(0, 1).contiguous()
            label = torch.zeros(num_sample, dtype=torch.int64, device=values.device)
            loss = torch.nn.functional.cross_entropy(values, label)
            return loss

        if compute_loss_c1r4:
            total_batch_size = input_ids.size(0)
            assert total_batch_size % 5 == 0 and total_batch_size == len(values)
            values = values.float()
            num_sample = total_batch_size // 5

            values = values.view(num_sample, 5).contiguous()
            chosen = values[:, 0]
            reject1 = values[:, 1]
            reject2 = values[:, 2]
            reject3 = values[:, 3]
            reject4 = values[:, 4]
            loss = (
                - torch.nn.functional.logsigmoid(chosen - reject1)
                - torch.nn.functional.logsigmoid(chosen - reject2)
                - torch.nn.functional.logsigmoid(chosen - reject3)
                - torch.nn.functional.logsigmoid(chosen - reject4)
            ).mean()
            return loss

        if compute_loss_c1r4_new:
            total_batch_size = input_ids.size(0)
            assert total_batch_size % 5 == 0 and total_batch_size == len(values)
            values = values.float()
            num_sample = total_batch_size // 5

            values = values.view(num_sample, 5).contiguous()
            label = torch.zeros(num_sample, dtype=torch.int64, device=values.device)
            loss = torch.nn.functional.cross_entropy(values, label)
            return loss

        return values

"""
Use those models for specific experiments,
so you need to modify datasets and dataloader
to satissfy the input format and the loss calculation
of the model
"""

class LlamaForPerplexity(LlamaForCausalLM):
    def __init__(self, config):
        super().__init__(config)

        self.llama.kv_enabled(False)
        self.llama.fmha_enabled(True)

        # self.lm_loss = nn.CrossEntropyLoss(reduction="none")

    def generate(self, prompts, tokenizer, max_length=1024, sample=False, mpu=None):
        if mpu is not None:
            dp_rank = mpu.get_data_parallel_rank()
            dp_size = mpu.get_data_parallel_world_size()
            length_per_rank = len(prompts) // dp_size
            start = dp_rank * length_per_rank
            end = (dp_rank + 1) * length_per_rank
            end = end if end < len(prompts) else len(prompts)
            rank_prompts = prompts[start:end]
            prompts = rank_prompts

        tokenizer.padding_side = "left"
        self.llama.fmha_enabled(False)
        self.llama.kv_enabled(True)
        _forward = self.forward
        self.forward = lambda *args, **kwargs: LlamaForCausalLM.forward(
            self, *args, **kwargs
        )
        # stages = [(400, 450, 64), (550, 600, 64), (700, 750, 32)]
        generator = Generator(
            self,
            tokenizer,
            prompts,
            max_length=max_length,
            stages=None,
        )
        outs = generator.run()
        self.forward = _forward
        self.llama.fmha_enabled(True)
        self.llama.kv_enabled(False)

        if mpu is not None:
            dp_group = mpu.get_data_parallel_group()
            _outs = mpu.utils.gather_object(outs, dp_group)
            outs = []
            for out in _outs:
                outs.extend(out)

        tokenizer.padding_side = "right"
        return outs

    def forward(
        self,
        input_ids,
        attention_mask,
        position_ids: Optional[torch.LongTensor] = None,
        loss_mask=None,
        ppl_coef=0.3,
    ) -> torch.Tensor:  # return loss
        if loss_mask is None:
            loss_mask = attention_mask.float()

        if position_ids is None:
            # Position ids.
            batch_size, seq_length = input_ids.size()
            position_ids = torch.arange(
                seq_length, dtype=torch.long, device=input_ids.device
            )
            position_ids = position_ids.unsqueeze(0).expand_as(input_ids)

        total_batch_size = input_ids.size(0)
        outputs = self.llama(
            input_ids,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_values=None,
            use_cache=False,
            output_attentions=False,
            output_hidden_states=False,
            return_dict=False,
        )

        hidden_states = outputs[0]
        lm_logits = self.embed_out(hidden_states)[0]

        total_labels = input_ids[:, 1:].contiguous()
        loss_mask = loss_mask[:, :-1].contiguous()
        shift_logits = lm_logits[:, :-1, :].float().contiguous()

        # sum on seq_len dim
        logprobs = torch.nn.functional.log_softmax(shift_logits, dim=-1)
        values = torch.gather(logprobs, -1, total_labels.unsqueeze(-1)).squeeze(-1)
        values = values * loss_mask
        values = values.sum(dim=-1)

        num_sample = total_batch_size // 2
        chosen = values[:num_sample]
        reject = values[num_sample : 2 * num_sample]
        loss_logits = chosen - reject
        ppl_loss = -nn.functional.logsigmoid(loss_logits).mean()

        """
        LM loss (calc only on chosen part of batch)
        """
        chosen_logits = shift_logits[:num_sample]
        chosen_labels = total_labels[:num_sample]
        lm_loss_mask = loss_mask[:num_sample]
        lm_loss = nn.functional.cross_entropy(
            chosen_logits.view(-1, chosen_logits.size(-1)),
            chosen_labels.view(-1),
            reduction="none",
        )
        lm_loss = (lm_loss * lm_loss_mask.view(-1)).sum() / lm_loss_mask.sum()
        loss = ppl_coef * ppl_loss + (1 - ppl_coef) * lm_loss
        return loss


# INSERTION SORT IN PYTHON BY IAMSOMRAJ

def insertionSort(list):
    for i in range(1, len(list)):
        temp = list[i]
        j = i - 1
        while j >= 0 and list[j] > temp:
            list[j+1] = list[j]
            j = j - 1
        list[j+1] = temp
    print("\nThe given array after sorting becomes: \n")
    print(list)

n = int(input("\nEnter the number of elements : \n\n"))
print("\nEnter the elements one by one\n\n")
list = []
for i in range(n):
    list.append(int(input()))
print("\nThe given array is : \n")
print(list)
insertionSort(list)


def add(num1,num2):
    """Adddition funcction"""
    return num1+num2

def sub(num1,num2):
    """Substractoin funcction"""
    return num1-num2

def mul(num1,num2):
    """Multiplication funcction"""
    return num1*num2

def div(num1,num2):
    """Division funcction"""
    return num1/num2

"""Display all the options available for calculation"""
print("Calculator")
print("1. Addition")
print("2. Substraction")
print("3. MMultiplication")
print("4. Division")

"""Get the input choice from the Client"""
choice = input("Enter choice")

"""Get the number input from the client"""
num1 = int(input("Enter Number1"))
num2 = int(input("Enter Number2"))

"""Check the choice using the If statement and call the respecctive functions"""
if choice == '1':
    print("Addition of ",num1,"and",num2,"is ",add(num1,num2))
elif choice == '2':
    print("Subtraction of ", num1, "and", num2, "is ", sub(num1, num2))
elif choice == '3':
    print("Multiploication of ", num1, "and", num2, "is ", mul(num1, num2))
elif choice == '4':
    print("Division of ", num1, "and", num2, "is ", div(num1, num2))
else:
    print("invalid input")


import os

import click

from openpype.modules import (
    OpenPypeModule,
    ITrayModule,
    IPluginPaths,
)
from openpype.lib import Logger

FTRACK_MODULE_DIR = os.path.dirname(os.path.abspath(__file__))
_URL_NOT_SET = object()

class FtrackModule(
    OpenPypeModule,
    ITrayModule,
    IPluginPaths,
):
    name = "ftrack"
    enabled = True

    def initialize(self, settings):
        ftrack_settings = settings[self.name]

        self._settings_ftrack_url = ftrack_settings["ftrack_server"]
        self._ftrack_url = _URL_NOT_SET

        current_dir = os.path.dirname(os.path.abspath(__file__))

        # User event handler paths
        user_event_handlers_paths = [
            os.path.join(current_dir, "event_handlers_user")
        ]

        # Prepare attribute
        self.user_event_handlers_paths = user_event_handlers_paths
        self.tray_module = None

        # TimersManager connection
        self.timers_manager_connector = None
        self._timers_manager_module = None

    def get_ftrack_url(self):
        """Resolved ftrack url.

        Resolving is trying to fill missing information in url and tried to
        connect to the server.

        Returns:
            Union[str, None]: Final variant of url or None if url could not be
                reached.
        """

        if self._ftrack_url is _URL_NOT_SET:
            self._ftrack_url = resolve_ftrack_url(
                self._settings_ftrack_url,
                logger=self.log
            )
        return self._ftrack_url

    ftrack_url = property(get_ftrack_url)

    @property
    def settings_ftrack_url(self):
        """Ftrack url from settings in a format as it is.

        Returns:
            str: Ftrack url from settings.
        """

        return self._settings_ftrack_url

    def get_global_environments(self):
        """Ftrack's global environments."""

        return {
            "FTRACK_SERVER": self.ftrack_url
        }

    def get_plugin_paths(self):
        """Ftrack plugin paths."""
        return {
            "publish": [os.path.join(FTRACK_MODULE_DIR, "plugins", "publish")]
        }

    def get_launch_hook_paths(self):
        """Implementation for applications launch hooks."""

        return os.path.join(FTRACK_MODULE_DIR, "launch_hooks")

    def modify_application_launch_arguments(self, application, env):
        if not application.use_python_2:
            return

        self.log.info("Adding Ftrack Python 2 packages to PYTHONPATH.")

        # Prepare vendor dir path
        python_2_vendor = os.path.join(FTRACK_MODULE_DIR, "python2_vendor")

        # Add Python 2 modules
        python_paths = [
            # `python-ftrack-api`
            os.path.join(python_2_vendor, "ftrack-python-api", "source"),
        ]

        # Load PYTHONPATH from current launch context
        python_path = env.get("PYTHONPATH")
        if python_path:
            python_paths.append(python_path)

        # Set new PYTHONPATH to launch context environments
        env["PYTHONPATH"] = os.pathsep.join(python_paths)

    def connect_with_modules(self, enabled_modules):
        for module in enabled_modules:
            if not hasattr(module, "get_ftrack_event_handler_paths"):
                continue

            try:
                paths_by_type = module.get_ftrack_event_handler_paths()
            except Exception:
                continue

            if not isinstance(paths_by_type, dict):
                continue

            for key, value in paths_by_type.items():
                if not value:
                    continue

                if key not in ("server", "user"):
                    self.log.warning(
                        "Unknown event handlers key \"{}\" skipping.".format(
                            key
                        )
                    )
                    continue

                if not isinstance(value, (list, tuple, set)):
                    value = [value]

                if key == "user":
                    self.user_event_handlers_paths.extend(value)

    def create_ftrack_session(self, **session_kwargs):
        import ftrack_api

        if "server_url" not in session_kwargs:
            session_kwargs["server_url"] = self.ftrack_url

        api_key = session_kwargs.get("api_key")
        api_user = session_kwargs.get("api_user")
        # First look into environments
        # - both AYON tray and ftrack event server should have set them
        # - ftrack event server may crash when credentials are tried to load
        #   from keyring
        if not api_key or not api_user:
            api_key = os.environ.get("FTRACK_API_KEY")
            api_user = os.environ.get("FTRACK_API_USER")

        if not api_key or not api_user:
            from .lib import credentials
            cred = credentials.get_credentials()
            api_user = cred.get("username")
            api_key = cred.get("api_key")

        session_kwargs["api_user"] = api_user
        session_kwargs["api_key"] = api_key
        return ftrack_api.Session(**session_kwargs)

    def tray_init(self):
        from .tray import FtrackTrayWrapper

        self.tray_module = FtrackTrayWrapper(self)
        # Module is it's own connector to TimersManager
        self.timers_manager_connector = self

    def tray_menu(self, parent_menu):
        return self.tray_module.tray_menu(parent_menu)

    def tray_start(self):
        return self.tray_module.validate()

    def tray_exit(self):
        self.tray_module.tray_exit()

    def set_credentials_to_env(self, username, api_key):
        os.environ["FTRACK_API_USER"] = username or ""
        os.environ["FTRACK_API_KEY"] = api_key or ""

    # --- TimersManager connection methods ---
    def start_timer(self, data):
        if self.tray_module:
            self.tray_module.start_timer_manager(data)

    def stop_timer(self):
        if self.tray_module:
            self.tray_module.stop_timer_manager()

    def register_timers_manager(self, timer_manager_module):
        self._timers_manager_module = timer_manager_module

    def timer_started(self, data):
        if self._timers_manager_module is not None:
            self._timers_manager_module.timer_started(self.id, data)

    def timer_stopped(self):
        if self._timers_manager_module is not None:
            self._timers_manager_module.timer_stopped(self.id)

    def get_task_time(self, project_name, asset_name, task_name):
        session = self.create_ftrack_session()
        query = (
            'Task where name is "{}"'
            ' and parent.name is "{}"'
            ' and project.full_name is "{}"'
        ).format(task_name, asset_name, project_name)
        task_entity = session.query(query).first()
        if not task_entity:
            return 0
        hours_logged = (task_entity["time_logged"] / 60) / 60
        return hours_logged

    def get_credentials(self):
        # type: () -> tuple
        """Get local Ftrack credentials."""
        from .lib import credentials

        cred = credentials.get_credentials(self.ftrack_url)
        return cred.get("username"), cred.get("api_key")

    def cli(self, click_group):
        click_group.add_command(cli_main)

def _check_ftrack_url(url):
    import requests

    try:
        result = requests.get(url, allow_redirects=False)
    except requests.exceptions.RequestException:
        return False

    if (result.status_code != 200 or "FTRACK_VERSION" not in result.headers):
        return False
    return True

def resolve_ftrack_url(url, logger=None):
    """Checks if Ftrack server is responding."""

    if logger is None:
        logger = Logger.get_logger(__name__)

    url = url.strip("/ ")
    if not url:
        logger.error("Ftrack URL is not set!")
        return None

    if not url.startswith("http"):
        url = "https://" + url

    ftrack_url = None
    if url and _check_ftrack_url(url):
        ftrack_url = url

    if not ftrack_url and not url.endswith("ftrackapp.com"):
        ftrackapp_url = url + ".ftrackapp.com"
        if _check_ftrack_url(ftrackapp_url):
            ftrack_url = ftrackapp_url

    if not ftrack_url and _check_ftrack_url(url):
        ftrack_url = url

    if ftrack_url:
        logger.debug("Ftrack server \"{}\" is accessible.".format(ftrack_url))

    else:
        logger.error("Ftrack server \"{}\" is not accessible!".format(url))

    return ftrack_url

@click.group(FtrackModule.name, help="Ftrack module related commands.")
def cli_main():
    pass


import numpy as np
import tensorflow as tf

class ZeroBaseline:
    def reset(self, session):
        pass

    def evaluate(self, episode, goal):
        return np.zeros(episode.length - 1, dtype=np.float32)

    def train_step(self, episodes):
        return 0.

class AdaptiveOptimumValueBaseline:
    def __init__(self, env, learning_rate=0.2):
        self.env = env
        self.learning_rate = learning_rate

    def reset(self, session):
        self.correction = np.zeros(self.env.max_steps - 1, dtype=np.float32)

    def evaluate(self, episode, goal):
        v = self.env.evaluate_values(episode, goal)
        return v + self.correction[: episode.length - 1]

    def train_step(self, episodes):
        max_steps = max([e.length for e in episodes])

        correction = np.zeros(max_steps - 1, dtype=np.float32)
        correction_n = np.zeros(max_steps - 1, dtype=np.float32)

        for i, e in enumerate(episodes):
            v = self.env.evaluate_values(e, e.goal)

            crewards = np.cumsum(e.rewards[1:][::-1])[::-1]

            correction[:e.length - 1] += crewards - v
            correction_n[:e.length - 1] += 1.0

        correction = correction/correction_n
        d = correction - self.correction[:max_steps - 1]
        self.correction[:max_steps - 1] += self.learning_rate*d

        return np.mean(d**2)

class BatchVariables:
    def __init__(self, d_observations, d_goals):
        self.d_observations = d_observations
        self.d_goals = d_goals

        self.d_input = d_observations + d_goals + 1

        self.lengths = tf.placeholder(tf.int32, [None], name='lengths')

        self.observations = tf.placeholder(tf.float32, [None, None,
                                                        d_observations],
                                           name='observations')
        self.rewards = tf.placeholder(tf.float32, [None, None], name='rewards')

        self.goals = tf.placeholder(tf.float32, [None, d_goals], 'goals')

        self.times = tf.placeholder(tf.float32, [None, None], name='times')

        self.batch_size = tf.shape(self.observations)[0]
        self.max_steps = tf.shape(self.observations)[1]

        self.goals_enc = tf.tile(self.goals, [1, self.max_steps])
        self.goals_enc = tf.reshape(self.goals_enc, [-1, self.max_steps,
                                                     self.d_goals])

        times = tf.expand_dims(self.times, axis=2)
        self.inputs = tf.concat([self.observations, self.goals_enc, times],
                                axis=2)

class ValueBaseline:
    def __init__(self, env, hidden_layers, learning_rate):
        self.env = env
        self.hidden_layers = hidden_layers
        self.learning_rate = learning_rate

        self.create_network()
        self.setup()

    def create_network(self):
        self.bvars = BatchVariables(self.env.d_observations, self.env.d_goals)

        output = tf.reshape(self.bvars.inputs, [-1, self.bvars.d_input])

        self.variables = []
        layers = [self.bvars.d_input] + self.hidden_layers + [1]
        for i in range(1, len(layers)):
            W = tf.Variable(tf.truncated_normal([layers[i - 1], layers[i]],
                                                stddev=0.01),
                            name='vW_{0}'.format(i))
            b = tf.Variable(tf.zeros(layers[i]), name='vb_{0}'.format(i))

            self.variables += [W, b]

            output = tf.matmul(output, W) + b
            if i < len(layers) - 1:
                output = tf.tanh(output)

        self.pred = tf.reshape(output, [-1, self.bvars.max_steps])

    def setup(self):
        # Ignoring prediction for last time step
        mask = tf.sequence_mask(self.bvars.lengths - 2,
                                self.bvars.max_steps - 1, dtype=tf.float32)
        pred = tf.stop_gradient(self.pred[:, 1:])*mask

        mask = tf.sequence_mask(self.bvars.lengths - 1, dtype=tf.float32)
        rewards = self.bvars.rewards[:, 1:]*mask

        target = rewards + pred

        self.loss = ((self.pred[:, :-1] - target)**2)*mask
        self.loss = tf.reduce_sum(self.loss)/tf.reduce_sum(mask)

        optimizer = tf.train.AdamOptimizer(self.learning_rate)
        self.train_op = optimizer.minimize(self.loss)

    def reset(self, session):
        self.session = session

    def evaluate(self, episode, goal):
        feed = {self.bvars.lengths: [episode.length - 1],
                self.bvars.observations: [episode.observations[:-1]],
                self.bvars.goals: [goal],
                self.bvars.times: [np.arange(1, episode.length)]}

        return self.session.run(self.pred, feed)[0]

    def train_step(self, episodes):
        lengths = np.array([e.length for e in episodes], dtype=np.int32)

        batch_size = len(episodes)
        max_steps = max(lengths)

        observations = np.zeros((batch_size, max_steps,
                                 self.bvars.d_observations), dtype=np.float32)
        rewards = np.zeros((batch_size, max_steps), dtype=np.float32)
        goals = np.array([e.goal for e in episodes], dtype=np.float32)

        times = np.zeros((batch_size, max_steps), dtype=np.float32)

        for i in range(batch_size):
            for j in range(lengths[i]):
                observations[i, j] = episodes[i].observations[j]

            rewards[i, :lengths[i]] = episodes[i].rewards

            times[i, :lengths[i]] = np.arange(1, lengths[i] + 1)

        feed = {self.bvars.lengths: lengths,
                self.bvars.observations: observations,
                self.bvars.rewards: rewards, self.bvars.goals: goals,
                self.bvars.times: times}

        loss, _ = self.session.run([self.loss, self.train_op], feed)

        return loss


def length(l):
    if l==[]:
        return 0
    try:
        le=l[0]/l[0]
    except:
        le=1
    return int(le)+length(l[1:])

s=input('Enter space seperated numbers\n')

lst=[int(x) for x in s.split()]

print('length =',length(lst))


import numpy as np
import pylab as py
import matplotlib.pyplot as plt
from matplotlib import rc
from scipy import interpolate
import sys

dir = '/mount/riachuelo1/hahn/data/manera_mock/dr11/'
n   = int(sys.argv[1])

name0   = 'cmass_dr11_north_ir4'
nameend = '.v7.0.'
for i in range(1,n+1):
    fname_wboss = 'nbar-normed-'+name0+str(i+1000)[1:4]+nameend+'wboss.txt'
    fname_upw   = 'nbar-normed-'+name0+str(i+1000)[1:4]+nameend+'upweight.txt'
    fname_peak  = 'nbar-normed-'+name0+str(i+1000)[1:4]+nameend+'peakcorr.txt'
    fname_rand  = 'nbar-normed-cmass_dr11_north_randoms_ir4'+str(i+1000)[1:4]+nameend+'wghtv.txt'
    fname_randp = 'nbar-normed-cmass_dr11_north_randoms_ir4'+str(i+1000)[1:4]+nameend+'peakcorr.txt'

    data_wboss  = np.loadtxt(dir+fname_wboss)
    data_upw    = np.loadtxt(dir+fname_upw)
    data_peak   = np.loadtxt(dir+fname_peak)
    data_rand   = np.loadtxt(dir+fname_rand)
    data_randp  = np.loadtxt(dir+fname_randp)

    if i==1:
        x_axis      = data_wboss[:,0]
        sum_wboss   = data_wboss[:,3]
        sum_upw     = data_upw[:,3]
        sum_peak    = data_peak[:,3]
        sum_rand    = data_rand[:,3]
        sum_randp   = data_randp[:,3]
    else:
        sum_wboss   = sum_wboss+data_wboss[:,3]
        sum_upw     = sum_upw+data_upw[:,3]
        sum_peak    = sum_peak+data_peak[:,3]
        sum_rand    = sum_rand+data_rand[:,3]
        sum_randp   = sum_randp+data_randp[:,3]
ratio_peak_upw      = sum_peak/sum_upw

for i in range(len(ratio_peak_upw)):
    if x_axis[i] < 0.43 or x_axis[i] > 0.7:
        ratio_peak_upw[i] = 1.0

pthalo_fname    = 'nbar-dr10v5-N-Anderson'
pthalo_data     = np.loadtxt(dir+pthalo_fname+'.dat')

pthalo_data[:,3] = ratio_peak_upw*pthalo_data[:,3]

corrected_fname = pthalo_fname+'-peaknbarcorr.dat'
corrected_file  = open(dir+corrected_fname,'w')
for i in range(len(pthalo_data[:,3])):
    corrected_file.write(str(pthalo_data[i,0])+'\t'+str(pthalo_data[i,1])+'\t'+str(pthalo_data[i,2])+'\t'+str(pthalo_data[i,3])+'\n')
exit()


import glob
import os.path
from os.path import basename
from typing import Dict, Optional

from PIL import Image, ImageFile

import tifffile

import torch
from torch import Tensor
from torch.utils.data import Dataset

ImageFile.LOAD_TRUNCATED_IMAGES = True

class DaVinciEnsembleDataset(Dataset):
    """Dataset class for loading the Hamlyn da Vinci images.

    Given the root of the dataset path, this class will find all left and
    right `.png` images and collect each pair as a dictionary of Tensors.

    If there are any missing image IDs from either left or right folders,
    the pair is ignored.

    Note:
        Transforms must be able to handle dictionaries containing left and
        right views as separate entries.

    Args:
        root (str): Path to the root of the dataset directory.
        split (str): The folder in the dataset to use. Must be "train" or
            "test".
        transform (Optional[object], optional): The transforms to apply to
            each image pair while loading. Defaults to None.
        limit (Optional[int], optional): The maximum number of images to load.
            Loads all images if None. Defaults to None.
    """
    LEFT_PATH = 'image_0'
    RIGHT_PATH = 'image_1'
    IMAGE_EXT = 'png'
    ENSEMBLE_EXT = 'tiff'

    def __init__(self, davinci_path: str, ensemble_path: str, split: str,
                 transform: Optional[object] = None,
                 limit: Optional[int] = None) -> None:

        if split not in ('train', 'test'):
            raise ValueError('Split must be either "train" or "test".')

        left_glob = os.path.join(davinci_path, split, self.LEFT_PATH,
                                 f'*.{self.IMAGE_EXT}')

        right_glob = os.path.join(davinci_path, split, self.RIGHT_PATH,
                                  f'*.{self.IMAGE_EXT}')

        ensemble_glob = os.path.join(ensemble_path, split,
                                     f'*.{self.ENSEMBLE_EXT}')

        left = glob.glob(left_glob)
        right = glob.glob(right_glob)

        ensemble = glob.glob(ensemble_glob)

        left_names = set(map(self.name, left))
        right_names = set(map(self.name, right))
        ensemble_names = set(map(self.name, ensemble))

        stereo_missing = left_names.symmetric_difference(right_names)
        ensemble_missing = left_names.symmetric_difference(ensemble_names)

        missing = set.union(stereo_missing, ensemble_missing)

        if len(missing) > 0:
            print(f'Missing {len(missing):,} images from the dataset.')
            left = [i for i in left if self.name(i) not in missing]
            right = [i for i in right if self.name(i) not in missing]
            ensemble = [i for i in ensemble if self.name(i) not in missing]
            print(f'Dataset reduced to {len(left):,} images.')

        self.lefts = sorted(left[:limit])
        self.rights = sorted(right[:limit])

        self.ensembles = sorted(ensemble[:limit])

        self.transform = transform

    @staticmethod
    def name(path: str) -> str:
        return os.path.splitext(basename(path))[0]

    def __getitem__(self, idx: int) -> Dict[str, Tensor]:
        """Retrieve a single sample from the dataset.

        Args:
            idx (int): The index of the sample in the dataset.

        Returns:
            Dict[str, Tensor]: The left and right images packaged as a
                dictionary containing `left` and `right` keys.
        """
        left_path = self.lefts[idx]
        right_path = self.rights[idx]

        ensemble_path = self.ensembles[idx]

        left = Image.open(left_path).convert('RGB')
        right = Image.open(right_path).convert('RGB')

        ensemble_prediction = tifffile.imread(ensemble_path)

        image_pair = {
            'left': left, 'right': right,
            'ensemble': torch.from_numpy(ensemble_prediction)
        }

        if self.transform is not None:
            image_pair = self.transform(image_pair)

        return image_pair

    def __len__(self) -> int:
        return len(self.lefts)


# -*- coding: utf-8 -*-
from models.model import Model
from models.blog import Blog
from dae.api.sqlstore import store
from dae.api import doubanusers

class Comment(Model):

    __table__ = 'mini_comment'

    __all__ = 'id, blog_id, content, create_time, creator_id'

    def __init__(self, id, blog_id, content,
                 create_time, creator_id):
        self.id = id
        self.blog_id = blog_id
        self.content = content
        self.create_time = create_time
        self.creator_id = creator_id

    @classmethod
    def get(cls, id):
        sql = 'select {} from {} where id=%s'.format(cls.__all__, cls.__table__)
        rs = store.execute(sql, id)
        return cls(*rs[0]) if rs and rs[0] else None

    @classmethod
    def get_all(cls):
        sql = 'select {} from {}'.format(cls.__all__, cls.__table__)
        rs = store.execute(sql)
        return [cls(*r) for r in rs] if rs else None

    @classmethod
    def create(cls, blog_id, content, creator_id):
        sql = 'insert into {} (blog_id,content,creator_id) values(%s, %s, %s)'.format(cls.__table__)
        params = (blog_id, content, creator_id)
        id = store.execute(sql,params)
        store.commit()
        if id:
            blog = Blog.get(blog_id)
            blog.add_comment_count(1)
        return id

    def delete(self):
        sql = 'delete from {} where id=%s'.format(self.__table__)
        store.execute(sql, self.id)
        store.commit()
        blog = Blog.get(self.blog_id)
        blog.add_comment_count(-1)

    @classmethod
    def get_comments(cls, blog_id):
        sql = 'select {} from {} where blog_id=%s'.format(cls.__all__, cls.__table__)
        rs = store.execute(sql, blog_id)
        return [cls(*r) for r in rs] if rs else None

    def get_creator(self):
        creator = doubanusers.User(self.creator_id)
        return creator


numbers = [1, 2, 3, 1, 1, 3]

class Solution:
    def numIdenticalPairs(self, nums) -> int:
        ans = 0
        for i in range(len(nums)-1):
            for j in range(i+1, len(nums)):
                if nums[i] == nums[j]:
                    ans += 1
        return ans

slt = Solution()
print(slt.numIdenticalPairs(numbers))

Python/easy/1512. Number of Good Pairs.py


from googlesearch import search
import requests
from bs4 import BeautifulSoup
import csv

def join_results(hits_list):
    hits = ''
    for x in hits_list:
        hits += str(x)
    return hits

def grab_links(site, word):
    links_list = []
    for l in search(site+word, tld='com', lang='en', num=10, start=0, stop=10, pause=2.0):
        links_list.append(l)
    return links_list

def grab_results(site, word):
    with requests.Session() as s:
        url = f"http://www.google.com/search?q={site}+{word}"
        headers = {
            "referer":"referer: https://www.google.com/",
            "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
                         " (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
            }
        s.post(url, headers=headers)
        response = s.get(url, headers=headers)
        soup = BeautifulSoup(response.content, 'html.parser')
        result_list = soup.find_all(id='result-stats')[0].text
        results_string = join_results([int(s) for s in result_list.split() if s.isdigit()])
    return f"{word}: {results_string}"

keywords = open('keywords.txt', 'r').read().split(" ")
query = 'site:https://www.searchenginejournal.com/'

for w in keywords:
    links = grab_links(query, w)
    with open("links.csv", "a", encoding='utf-8') as w_file:
        file_writer = csv.writer(w_file, delimiter=",", lineterminator="\n")
        for link in links:
            file_writer.writerow(link)
    results = grab_results(query, w)
    with open("results.csv", "a", encoding='utf-8') as w_file:
        file_writer = csv.writer(w_file, delimiter=",", lineterminator="\n")
        for result in results:
            file_writer.writerow(result)


# -*- coding: utf-8 -*-
import glob
import os

if __name__ == '__main__':

    root = os.path.expanduser('~/Data/CamVid')
    split = 'train'
    file_list = glob.glob(root + '/' + split + 'bbox/*.xml')
    file_list.sort()
    # print(file_list)

    img_file_count = 6690
    for bbox_path_name in file_list:
        img_file_name = bbox_path_name[bbox_path_name.rfind('/')+1:bbox_path_name.rfind('.')]
        if '001TP' in img_file_name:
            img_file_new_name = '0001TP_{:06d}'.format(img_file_count)
            img_file_count += 30
            print(bbox_path_name)
            print(img_file_name)
            print(img_file_new_name)
            bbox_path_new_name = root + '/' + split + 'bbox/{}.xml'.format(img_file_new_name)
            print(bbox_path_new_name)
            os.rename(bbox_path_name, bbox_path_new_name)


from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.stacklayout import StackLayout
from kivy.uix.tabbedpanel import TabbedPanelItem, TabbedPanel
from kivy.uix.textinput import TextInput

from tonguetwister.file_disassembler import FileDisassembler
from tonguetwister.gui.chunkviews.default import RawChunkView
from tonguetwister.gui.widgets.generic.props import MonoFont
from tonguetwister.gui.utils import load_script_function, update_text_area, highlight_word_in_text_area
from tonguetwister.lib.helper import exception_as_lines

class ScriptPanel(BoxLayout):
    current_function_index = NumericProperty(0)

    # TODO: Remove inspection warning
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.namelist = None

        self.current_script = None
        self.current_script_index = 0

        self.orientation = 'vertical'
        self.spacing = 0

        self.add_widget(self._build_action_bar())
        self.add_widget(self._build_panel())

    def _build_action_bar(self):
        next_function = Button(text='Next', width=50, size_hint_x=None)
        next_function.bind(on_press=lambda instance: self._update_function_index(1))
        prev_function = Button(text='Prev', width=50, size_hint_x=None)
        prev_function.bind(on_press=lambda instance: self._update_function_index(-1))

        self.function_index_label = Label(width=150, size_hint_x=None)
        self.function_name_label = Label()

        action_bar = StackLayout(orientation='rl-tb', height=30, size_hint_y=None)
        action_bar.add_widget(self.function_name_label)
        action_bar.add_widget(next_function)
        action_bar.add_widget(self.function_index_label)
        action_bar.add_widget(prev_function)

        return action_bar

    def _build_panel(self):
        self.text_area_generated = TextInput(font_name=MonoFont.font_name)
        self.text_area_reconstructed = TextInput(font_name=MonoFont.font_name)
        self.text_area_named = TextInput(font_name=MonoFont.font_name)
        self.text_area_raw = TextInput(font_name=MonoFont.font_name)
        self.text_area_chunk = RawChunkView(font_name=MonoFont.font_name)

        self.text_area_generated.bind(on_touch_down=self._on_text_area_touch_down)
        self.text_area_reconstructed.bind(on_touch_down=self._on_text_area_touch_down)
        self.text_area_named.bind(on_touch_down=self._on_text_area_touch_down)
        self.text_area_raw.bind(on_touch_down=self._on_text_area_touch_down)

        tab1 = TabbedPanelItem(text='Generated Code')
        tab1.add_widget(self.text_area_generated)
        tab2 = TabbedPanelItem(text='Reconstructed Ops')
        tab2.add_widget(self.text_area_reconstructed)
        tab3 = TabbedPanelItem(text='Named Ops')
        tab3.add_widget(self.text_area_named)
        tab4 = TabbedPanelItem(text='Raw ops')
        tab4.add_widget(self.text_area_raw)
        tab5 = TabbedPanelItem(text='Chunk info')
        tab5.add_widget(self.text_area_chunk)

        tabbed_panel = TabbedPanel(do_default_tab=False, tab_width=150, tab_height=30)
        tabbed_panel.add_widget(tab1)
        tabbed_panel.add_widget(tab2)
        tabbed_panel.add_widget(tab3)
        tabbed_panel.add_widget(tab4)
        tabbed_panel.add_widget(tab5)

        return tabbed_panel

    def load(self, file_disassembler: FileDisassembler, index, script):
        self.namelist = file_disassembler.namelist

        self.current_function_index = 0
        self.current_script_index = index
        self.current_script = script
        self._render_script()
        self.text_area_chunk.load(script)

    def _update_function_index(self, amount):
        n_functions = len(self.current_script.functions)

        self.current_function_index = (self.current_function_index + amount) % n_functions
        self._render_script()

    def _render_script(self):
        decompiler = load_script_function(
            self.current_script_index,
            self.current_function_index,
            self.namelist,
            self.current_script
        )

        Clock.schedule_once(lambda _: self._update_script_display(decompiler), 0)

    def _update_script_display(self, result):
        self.function_index_label.text = f'Function index: {self.current_function_index}'
        self.function_name_label.text = f'Function: {result.function_name}'

        generated_code_lines = exception_as_lines(result.exception) if result.has_exception() else result.generated_code

        update_text_area(self.text_area_raw, result.detokenized_operators, line_numbers=False)
        update_text_area(self.text_area_named, result.named_operators, line_numbers=False)
        update_text_area(self.text_area_reconstructed, result.reconstructed_operators)
        update_text_area(self.text_area_generated, generated_code_lines)

    @staticmethod
    def _on_text_area_touch_down(text_area, touch):
        if text_area.collide_point(*touch.pos) and not touch.is_double_tap:
            Clock.schedule_once(lambda _: highlight_word_in_text_area(text_area), 0)


class SuffixArray():
    def __init__(self, magic_string):
        self.magic_string = magic_string
        self.size = len(magic_string)
        self.suffix_array = []
        self.suftab = []
        self.sufinv = []
        self.lcp = []
        self.build_suffix_array()

    def build_suffix_array(self):
        for i in range(0, len(self.magic_string)):
            self.suffix_array.append([self.magic_string[i:], i])
        print(self.suffix_array)
        self.suffix_array = sorted(self.suffix_array) #Python's sorted uses TimSort so O(nlogn)
        print(self.suffix_array)
        self.suftab = []
        for j in range(0, len(self.suffix_array)):
            self.suftab.insert(j, self.suffix_array[j][1])
        #print(self.suffix_array, self.suftab, self.sufinv)
        for i, val in enumerate(self.suftab):
            self.sufinv.insert(val, i)
            #print(val, i, self.sufinv)
        length = 0
        n = len(self.suffix_array)
        for i in range(0, n):
            if self.sufinv[i] == n:
                length = 0
                #print(length)
                continue
            #if self.sufinv[i] > 0 :
            k = self.suffix_array[self.sufinv[i]-1][1]
            while i+length < n and k+length < n and \
                self.magic_string[i+length] ==  self.magic_string[k+length]:
                #print(self.magic_string[i+length], self.magic_string[k+length])
                length += 1
            self.lcp.insert(self.sufinv[i], length)
            #print(self.sufinv[i], length)
            if length > 0:
                length -= 1
        print(self.suffix_array, self.suftab, self.sufinv, self.lcp)

sa = SuffixArray("banana")
sa1 = SuffixArray("abaababbabbb$")
sa2 = SuffixArray("acaaacatat$")

from itertools import zip_longest, islice
def to_int_keys(l):
    """
    l: iterable of keys
    returns: a list with integer keys
    """
    seen = set()
    ls = []
    for e in l:
        if not e in seen:
            ls.append(e)
            seen.add(e)
    ls.sort()
    print(ls)
    index = {v: i for i, v in enumerate(ls)}
    print(index)
    return [index[v] for v in l]

def suffix_array(s):
    n = len(s)
    k = 1
    keys = to_int_keys(s)
    ans = [keys]
    while max(keys) < n-1 :
        keys = to_int_keys(
            list(zip_longest(keys, islice(keys, k, None), fillvalue=-1))
        )
        #print("w",list(zip_longest(keys, islice(keys, k, None), fillvalue=-1)))
        ans.append(keys)
        k << 1
    return ans

def lcp(sa, i, j):
    n = len(sa[-1])
    if i == j:
        return n-i
    k = 1 << (len(sa)-2)
    ans = 0
    for line in sa[-2::-1]:
        if i >= n or j >= n:
            break
        if line[i] == line[j]:
            ans ^= k
            i += k
            j += k
        k >>= 1
    return ans

print(lcp(suffix_array("banana"),2,4))


import requests
import sys
import pprint

import googleapiclient
from simple_youtube_api.YouTubeVideo import YouTubeVideo
from simple_youtube_api.Channel import Channel
from simple_youtube_api.YouTube import YouTube

from settings import *

def get_status(channel_credentials_file, youtube_video_id):
    channel = Channel()
    channel.login(
        CLIENT_SECRET_FILE,
        channel_credentials_file,
    )

    request = (
        channel.get_login()
        .videos()
        .list(
            id=youtube_video_id,
            part="processingDetails, status",
        )
    )

    response_items = None
    response = None

    try:
        response = request.execute()
        response_items = response["items"]

        if len(response_items) > 0:
            return {
                "uploadStatus": response_items[0]["status"]["uploadStatus"],
                "processingStatus": response_items[0]["processingDetails"][
                    "processingStatus"
                ],
            }
        else:
            return {"uploadStatus": "deleted"}

    except Exception as e:
        print("Error:")
        print(str(e))

        if response is not None:
            print("Response:")
            print(response)

    return None

def is_processing(channel_credentials_file, youtube_video_id):
    return get_status(channel_credentials_file, youtube_video_id) == "processing"


"""
File: 1_even_lines.py
Exercise: 16 - File Handling
Problem: 1 - Even Lines
Author: Ivaylo Stoyanov - Devihem
"""

# Opening the file in reading mode - variable name : read_file
with open('text.txt', 'r') as read_file:

    # Reading the text and make a copy in text
    text = read_file.readlines()

    # Symbols that must be replaced in 'text' with '@'
    replacing_symbols = ["-", ",", ".", "!", "?"]

    # For loop with size of step [2] , going through only the even lines, as per condition of the task
    for line_index in range(0, len(text), 2):

        for symbol in replacing_symbols:

            # replacing every symbol in the text with '@'
            text[line_index] = text[line_index].replace(symbol, '@')

        # Printing the text line before going out of the loop, using the same line_index
        # text at index[line_index] unpacked , split by ' '  and printed with reverse order
        print(*text[line_index].split()[::-1])


"""
this code is adapted from https://github.com/black7375/korean_ocr_using_pororo

Apache License 2.0 @yunwoong7
Apache License 2.0 @black7375
"""

"""
Pororo task-specific factory class

    isort:skip_file

"""

import logging
from typing import Optional
from .tasks.utils.base import PororoTaskBase

import torch

from .tasks import (
    PororoOcrFactory,
)

SUPPORTED_TASKS = {
    "ocr": PororoOcrFactory,
}

LANG_ALIASES = {
    "english": "en",
    "eng": "en",
    "korean": "ko",
    "kor": "ko",
    "kr": "ko",
    "chinese": "zh",
    "chn": "zh",
    "cn": "zh",
    "japanese": "ja",
    "jap": "ja",
    "jp": "ja",
    "jejueo": "je",
    "jje": "je",
}

logging.getLogger("transformers").setLevel(logging.WARN)
logging.getLogger("fairseq").setLevel(logging.WARN)
logging.getLogger("sentence_transformers").setLevel(logging.WARN)
logging.getLogger("youtube_dl").setLevel(logging.WARN)
logging.getLogger("pydub").setLevel(logging.WARN)
logging.getLogger("librosa").setLevel(logging.WARN)

class Pororo:
    r"""
    This is a generic class that will return one of the task-specific model classes of the library
    when created with the `__new__()` method

    """

    def __new__(
        cls,
        task: str,
        lang: str = "en",
        model: Optional[str] = None,
        **kwargs,
    ) -> PororoTaskBase:
        if task not in SUPPORTED_TASKS:
            raise KeyError(
                "Unknown task {}, available tasks are {}".format(
                    task,
                    list(SUPPORTED_TASKS.keys()),
                )
            )

        lang = lang.lower()
        lang = LANG_ALIASES[lang] if lang in LANG_ALIASES else lang

        # Get device information from torch API
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

        # Instantiate task-specific pipeline module, if possible
        task_module = SUPPORTED_TASKS[task](
            task,
            lang,
            model,
            **kwargs,
        ).load(device)

        return task_module

    @staticmethod
    def available_tasks() -> str:
        """
        Returns available tasks in Pororo project

        Returns:
            str: Supported task names

        """
        return "Available tasks are {}".format(list(SUPPORTED_TASKS.keys()))

    @staticmethod
    def available_models(task: str) -> str:
        """
        Returns available model names correponding to the user-input task

        Args:
            task (str): user-input task name

        Returns:
            str: Supported model names corresponding to the user-input task

        Raises:
            KeyError: When user-input task is not supported

        """
        if task not in SUPPORTED_TASKS:
            raise KeyError(
                "Unknown task {} ! Please check available models via `available_tasks()`".format(
                    task
                )
            )

        langs = SUPPORTED_TASKS[task].get_available_models()
        output = f"Available models for {task} are "
        for lang in langs:
            output += f"([lang]: {lang}, [model]: {', '.join(langs[lang])}), "
        return output[:-2]


import logging
import yaml
import os

class IndentDumper(yaml.Dumper):
    def increase_indent(self, flow=False, indentless=False):
        return super(IndentDumper, self).increase_indent(flow, False)

# 获取当前文件的绝对路径，然后构建config.yml文件的路径
current_dir = os.path.dirname(os.path.abspath(__file__))
config_file_path = os.path.join(current_dir, '../../conf/webhooks.yml')

def getconfig(filename=config_file_path):
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            return yaml.safe_load(file)
    else:
        default_config = []
        saveconfig(default_config)
        return default_config

def saveconfig(config_data, filename=config_file_path):
    with open(filename, 'w') as file:
        yaml.dump(config_data, file, default_flow_style=False,
                  allow_unicode=True, sort_keys=False, Dumper=IndentDumper)

def getWebhooksByEvent(event_name):
    '''根据事件类型获取webhooks'''
    allWebhooks = getconfig()
    webhooks = []
    for webhook in allWebhooks:
        if event_name in webhook.get('bindEvents', []):
            webhooks.append(webhook)
    return webhooks

def getAllWebhookEvents():
    '''获取所有webhook事件'''
    allWebhooks = getconfig()
    events = []
    for webhook in allWebhooks:
        events.extend(webhook.get('bindEvents', []))
    return list(set(events))


from django.shortcuts import render, redirect
from django.contrib.auth import login,logout,authenticate
from django.contrib.auth.forms import UserChangeForm
from .forms import RegisterForm, ProfileForm

# Create your views here.
def register(request):
    if request.method == "POST":
        form = RegisterForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request,user)
            return redirect("/home")
    else:
        form = RegisterForm()
    return render(request,'register.html',{"form":form})

# def login(request):
def usereditview(request):
    if request.method == "POST":
        form2 = ProfileForm(request.POST, instance=request.user)
        if form2.is_valid():
            form2.save()
            return redirect("/home")
    else:
        form2 = ProfileForm()
    return render(request,'edit_profile.html',{"form2":form2})


class Solution:
    """
    Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

    The overall run time complexity should be O(log (m+n)).

    Constraints:
    - nums1.length == m
    - nums2.length == n
    - 0 <= m <= 1000
    - 0 <= n <= 1000
    - 1 <= m + n <= 2000
    - -10^6 <= nums1[i], nums2[i] <= 10^6
    """

    def findMedianSortedArrays(self, nums1: list[int], nums2: list[int]) -> float:
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1

        m = len(nums1)
        n = len(nums2)
        low_1 = 0
        high_1 = m
        while low_1 <= high_1:
            # get middle index for nums1 and nums2
            mid_1 = (low_1 + high_1) // 2
            mid_2 = (m + n + 1) // 2 - mid_1

            # from these indexes get lower and upper median candidates for each array
            # if an index is out of bounds, use inf or -inf
            upper_1 = float("inf") if mid_1 == m else nums1[mid_1]
            lower_1 = float("-inf") if mid_1 == 0 else nums1[mid_1 - 1]
            upper_2 = float("inf") if mid_2 == n else nums2[mid_2]
            lower_2 = float("-inf") if mid_2 == 0 else nums2[mid_2 - 1]

            if lower_1 <= upper_2 and lower_2 <= upper_1:
                # current "lower" median candidates are both smaller equal to
                # the "upper" median candidate of the other array
                if (m + n) % 2 == 0:
                    # even total length, take average of two middle values
                    # middle values are largest lower candidate and smallest upper candidate
                    return (max(lower_1, lower_2) + min(upper_1, upper_2)) / 2
                else:
                    # odd length, take larger of the two values
                    return max(lower_1, lower_2)
            elif lower_1 > upper_2:
                # lower median candidate of first array is larger than
                # upper median candidate of second array, index mid_1
                # (and so also high_1) is too large to be a median candidate
                high_1 = mid_1 - 1
            else:  # lower_2 > upper_1
                # analogous to case above
                low_1 = mid_1 + 1

        assert False


# -*- coding: ISO-8859-1 -*-
'''
Par Jean-Sebastien Fauteux
Classe Serveur pour faire tourner le serveur du jeu
serveur.py
'''

import socket
import select
import pickle
import Netdata as nd
from time import sleep
import random

#Classe Wrapper pour les connexions clientes
class Client():
    def __init__(self, conn, address, id):
        self.conn = conn
        self.address = address
        self.id = id
        self.nom = ""
        self.race = ""

#Classe Wrapper pour les Joueurs
class Joueur():
    def __init__(self, client = Client(None, None, None), events = list()):
        self.client = client
        self.events = events

#Classe Serveur
class Serveur():
    def __init__(self, port = 43225):
        self.seed = random.randint(0,99999)
        self.port = port
        self.restart()
        self.listClientGone = []

        #Cr?ation du socket pour les connexions, ainsi que son param?trage
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(('', self.port))
        s.listen(5)
        self.socket = s

    def recevoirConnexion(self):
        #On va accepter les connexions uniquement si on est en-dessous du nombre de joueur maximal ou la partie n'est pas commenc?
        if self.qteConnect < self.maxConnect and self.statut == "demarrer":
            incoming, wlist, xlist = select.select([self.socket], [], [], 0.05) #Obtention de connexion
            for connection in incoming:
                conn, address = self.socket.accept()
                client = Client(conn, address, self.generateId())
                self.clients.append(client)

                #Envoi du Id au joueur
                clientId = nd.ClientId(client.id)
                bClientId = pickle.dumps(clientId)
                client.conn.send(bClientId)

        if self.statut == "jeu":
            if self.qteConnect == 0:
                print("REDEMARRAGE DU SERVEUR")
                self.restart()

    def restart(self):
        self.statut = "demarrer" #Le statut repr?sente l'?tat du serveur. demarrer(attend les connexions des joueurs), jeu(refuse les connexions)
        self.maxConnect = 8
        self.clients = [] #Maximum de 8, contient chaque client connect? au serveur
        self.qteConnect = len(self.clients)
        self.newClient = False
        self.listIdClient = nd.ListClientInfo()
        self.msgQueue = nd.MsgQueue()
        self.eventQueue = []
        self.treatedQueue = {}

        #Liste de bool?en pour les id des joueurs
        #Mis ? False par d?faut pour pouvoir les attribuer
        self.boolIdConnect = []
        for i in range(self.maxConnect):
            self.boolIdConnect.append(False)

        print("****** DEMARRAGE DU SERVEUR ******")
        print("******     PORT: " + str(self.port) + "      ******")
        print("******   MAX JOUEUR : " + str(self.maxConnect) + "     ******")

    def generateId(self):
        for i in range(self.maxConnect):
            if self.boolIdConnect[i] == False:
                self.boolIdConnect[i] = True
                return i
        return -1 #Aucun ID Disponible

    #Met ? jour le nombre de clients et les id dans la liste
    def updateQteClients(self):
        self.qteConnect = self.boolIdConnect.count(True)
        self.newClient = True
        self.listIdClient = nd.ListClientInfo()
        for client in self.clients:
            self.listIdClient.list.append(nd.ClientInfo(client.id, client.nom, client.race))

    def sendData(self):
        #On est pas encore dans le jeu, la seule chose qu'on envoie c'est la liste des clients
        if self.statut == "demarrer":
            if self.newClient == True:
                seedClient = nd.Seed(self.seed)
                bSeedClient = pickle.dumps(seedClient)
                bListClient = pickle.dumps(self.listIdClient)
                for client in self.clients:
                    client.conn.send(bListClient)
                    client.conn.send(bSeedClient)
            self.newClient = False

        elif self.statut == "starting":
            bListMsg = pickle.dumps(self.msgQueue)
            for client in self.clients:
                client.conn.send(bListMsg)
            self.msgQueue.msg = []

            self.statut = "jeu"
            print("****** DEMARRAGE D'UNE PARTIE ******")
        elif self.statut == "jeu":
            '''
            if len(self.listClientGone) == 0:
                clientsGone = nd.ClientDisconnect(self.listClientGone)
                bList = pickle.dumps(clientsGone)
                for client in self.clients:
                    client.conn.send(bList)
                self.listClientGone = []
            '''
            bEvents = pickle.dumps(self.treatedQueue)
            '''
            for frame in self.treatedQueue:
                item = self.treatedQueue[frame]
                print(item)
                sleep(1)
            '''
            for client in self.clients:
                '''
                for event in self.treatedQueue:
                    bEvent = pickle.dumps(event)
                    client.conn.send(bEvent)
                '''
                try:
                    client.conn.send(bEvents)
                except:
                    print("Erreur sur Envoie de client. Deconnection: ")
                    self.removeClient(client.conn)
                '''
                for event in self.treatedQueue:
                    for cl in self.treatedQueue[event]:
                        print(cl.events)
                '''

            self.treatedQueue = {}

    def getListConn(self):
        listConn = []
        for client in self.clients:
            listConn.append(client.conn)
        return listConn

    def findClientByConnection(self, conn):
        for client in self.clients:
            if client.conn == conn:
                return client
        return None

    def removeClient(self, conn):
        client = self.findClientByConnection(conn)
        self.boolIdConnect[client.id] = False
        self.listClientGone.append(client.id)
        self.clients.remove(client)
        self.updateQteClients()

    def recvData(self):
        if self.clients:
            toRead = []
            try:
                listConn = self.getListConn()
                toRead, wlist, xlist = select.select(listConn, [], [], 0.05)
            except select.error as serror:
                print("Select error: ", serror)
            else:
                for conn in toRead:
                    try:
                        bData = conn.recv(4096)
                        if bData:
                            data = pickle.loads(bData)
                            if isinstance(data, nd.ClientInfo): #R?cup?ration des infos du joueur
                                print("New client: " + str(data.nom) + " / " + str(data.race))
                                client = self.findClientByConnection(conn)
                                client.nom = data.nom
                                client.race = data.race
                                self.updateQteClients()
                            elif isinstance(data, nd.ClientDisconnect):
                                print("Client disconnected")
                                bDisco = pickle.dumps(nd.ClientDisconnect(data.id))
                                conn.send(bDisco)
                                self.removeClient(conn)
                            elif isinstance(data, nd.StartGameMsg):
                                self.statut = "starting"
                                self.msgQueue.msg.append(data)
                            elif isinstance(data, nd.ClientTickInfo):
                                self.eventQueue.append(data)
                            elif isinstance(data, nd.ClientTireInfo):
                                print("works")
                                pass
                    except Exception as ex:
                        print("Erreur sur lecture de client. Deconnection: ")
                        self.removeClient(conn)

    def updateFrames(self):
        if self.statut == "jeu":
            for event in self.eventQueue:
                self.treatedQueue[event.tick+5] = []

            for event in self.eventQueue:
                self.treatedQueue[event.tick+5].append(nd.ClientTickData(event.id, event.events))

            '''
            for frame in self.treatedQueue:
                events = self.treatedQueue[frame]
                for data in events:
                    print(data.id, data.events)
            '''
            sleep(0.05)

            self.eventQueue = []

serveur = Serveur()
while True:
    serveur.recevoirConnexion()
    serveur.sendData()
    serveur.recvData()
    serveur.updateFrames()


import base64

from odoo import http
from odoo.http import content_disposition, request

class BankRecoReport(http.Controller):
    @http.route(
        "/web/binary/jic_attendance_report",
        type="http",
        auth="user",
        sitemap=False,
    )
    def download_jic_attendance_report(self, wizard_id, **kw):
        model = request.env["hr.attendance.report.wizard"]
        case = model.browse(int(wizard_id))
        filename = "jic_report_attendance.xlsx"
        if case and case.report_file:
            file_data = base64.b64decode(case.report_file)
            return request.make_response(
                file_data,
                headers=[
                    ("Content-Disposition", content_disposition(filename)),
                    ("Content-Type", "application/vnd.ms-excel"),
                    ("Content-Length", len(filename)),
                ],
                cookies={"fileToken": ""},
            )


def plus_minus(a_list, n):
    pos_num, neg_num, zero_num = 0, 0 ,0
    for ele in a_list:
        if ele > 0:
            pos_num += 1
        elif ele < 0:
            neg_num += 1
        else:
            zero_num += 1

    print('{0:.6f}'.format(pos_num / n),
        '{0:.6f}'.format(neg_num / n),
        '{0:.6f}'.format(zero_num / n),
        sep='\n')

if __name__ == "__main__":
    n = int(input().strip())
    arr = list(map(int, input().rstrip().split()))
    plus_minus(arr, n)

HackerRank/3 Month Preparation Kit/1PlusMinus.py


#!/usr/bin/env python3
import numpy as np

def sigmoid(x, deriv=False):
    if(deriv):
        return np.multiply(x, 1.0 - x)
    return 1/(1+np.exp(-x))

class NeuralNetwork:

    def __init__(self, num_inputs, num_hidden, num_outputs, learning_rate):
        #Takes in the number of input neurons, hidden neurons, and output neurons
        self.num_inputs = num_inputs
        self.num_hidden = num_hidden
        self.num_outputs = num_outputs
        self.learning_rate = learning_rate

        #Creates Weight and bias matrices based on number of neurons in input, hidden and output
        self.weights0 = np.random.uniform(low=-1.0,high=1.0, size=(self.num_hidden, self.num_inputs))
        self.bias0 = np.random.uniform(low=-1.0,high=1.0, size=(self.num_hidden, 1))
        self.weights1 = np.random.uniform(low=-1.0,high=1.0, size=(self.num_outputs, self.num_hidden))
        self.bias1 = np.random.uniform(low=-1.0,high=1.0, size=(self.num_outputs, 1))

    def train(self, inputs, outputs):
        #-------------------------------------------------------------------------------------
        #For user conveniance, the input array is transposed into a column vector
        inputs = np.array([inputs])
        inputs = inputs.transpose()
        hidden_nodes = (np.dot(self.weights0, inputs)) + self.bias0
        #Pipe the hidden nodes through the sigmoid function to squish it between 1 and 0
        hidden_nodes = sigmoid(hidden_nodes)
        #Calculates the dot product of weights between 2nd and 3rd layer and adds bias on top
        output_nodes = np.dot(self.weights1, hidden_nodes) + self.bias1
        #Pipes all of the output through the sigmoid function to squish it between 1 and 0
        predictions = sigmoid(output_nodes)
        #---------------------------------------------------------------------------------------

        #Layer Between Hidden and Output

        #For user conveniance, the outputs array is transposed into a column vector
        outputs = np.array([outputs])
        outputs = outputs.transpose()

        #Get Error of output, ERROR = PREDICTION - ANSWER
        output_errors = (predictions - outputs)

        #Calculate Gradients (Using element-wise multiplication)
        output_gradients = sigmoid(predictions, deriv=True)
        output_gradients *= output_errors

        #Calculate hidden -> output Deltas
        hidden_nodes_transpose = hidden_nodes.transpose()
        weights1_deltas = output_gradients * hidden_nodes_transpose
        bias1_deltas = output_gradients

        self.weights1 = self.weights1 - weights1_deltas * self.learning_rate
        self.bias1 = self.bias1 - bias1_deltas * self.learning_rate

        #Layer between Input and Hidden

        #Get the transpose of the weight matrix from hidden -> output
        weights1_transpose = self.weights1.transpose()

        #Calculate the error for each of the hidden neurons using matrix multiplication
        # hidden_errors = weights1_transpose * sigmoid(predictions, deriv=True) * output_errors

        #Calculate hidden gradient
        hidden_gradients = sigmoid(hidden_nodes, deriv=True)
        hidden_gradients *= output_gradients * weights1_transpose

        #Calculate input -> hidden Deltas
        inputs_transpose = inputs.transpose()
        weights0_deltas = hidden_gradients * inputs_transpose
        bias0_deltas = hidden_gradients

        self.weights0 = self.weights0 - weights0_deltas * self.learning_rate
        self.bias0 = self.bias0 - bias0_deltas * self.learning_rate

    def predict(self, inputs):
        #For user conveniance, the input array is transposed into a column vector
        inputs = np.array([inputs])
        inputs = inputs.transpose()
        #Feed forward algortihm, using matrices and weighted sums, we can receive inputs through
        #the input neurons, feed them forward to the hidden layer using dot products, and finally
        #bring them to the output layer with one last dot product, lastly we use the sigmoid
        #activation function to squish the output between 1 and 0 for all neurons.

        #Calculates the dot product of weights between 1st and 2nd layer and adds bias on top
        hidden_nodes = (np.dot(self.weights0, inputs)) + self.bias0
        #Pipe the hidden nodes through the sigmoid function to squish it between 1 and 0
        hidden_nodes = sigmoid(hidden_nodes)

        #Calculates the dot product of weights between 2nd and 3rd layer and adds bias on top
        output_nodes = np.dot(self.weights1, hidden_nodes) + self.bias1
        #Pipes all of the output through the sigmoid function to squish it between 1 and 0
        output = sigmoid(output_nodes)

        return output