"""
======================
Polypeptide Initiation
======================

This process models the complementation of 30S and 50S ribosomal subunits
into 70S ribosomes on mRNA transcripts. This process is in many ways
analogous to the TranscriptInitiation process - the number of initiation
events per transcript is determined in a probabilistic manner and dependent
on the number of free ribosomal subunits, each mRNA transcript’s translation
efficiency, and the counts of each type of transcript.
"""

import numpy as np

from vivarium.core.composition import simulate_process
from ecoli.library.schema import (create_unique_indexes, numpy_schema, attrs,
    counts, bulk_name_to_idx, listener_schema)

from wholecell.utils import units
from wholecell.utils.fitting import normalize

from ecoli.processes.registries import topology_registry
from ecoli.processes.partition import PartitionedProcess

# Register default topology for this process, associating it with process name
NAME = 'ecoli-polypeptide-initiation'
TOPOLOGY = {
    "environment": ("environment",),
    "listeners": ("listeners",),
    "active_ribosome": ("unique", "active_ribosome"),
    "RNA": ("unique", "RNA"),
    "bulk": ("bulk",),
    "timestep": ("timestep",)
}
topology_registry.register(NAME, TOPOLOGY)

class PolypeptideInitiation(PartitionedProcess):
    """ Polypeptide Initiation PartitionedProcess """

    name = NAME
    topology = TOPOLOGY
    defaults = {
        'protein_lengths': [],
        'translation_efficiencies': [],
        'active_ribosome_fraction': {},
        'elongation_rates': {},
        'variable_elongation': False,
        'make_elongation_rates': lambda x: [],
        'rna_id_to_cistron_indexes': {},
        'cistron_start_end_pos_in_tu': {},
        'tu_ids': [],
        'active_ribosome_footprint_size': 24 * units.nt,
        'cistron_to_monomer_mapping': {},
        'cistron_tu_mapping_matrix': {},
        'monomer_index_to_cistron_index': {},
        'monomer_index_to_tu_indexes': {},
        'ribosome30S': 'ribosome30S',
        'ribosome50S': 'ribosome50S',
        'seed': 0,
        'monomer_ids': [],
        'emit_unique': False,
        'time_step': 1,
    }

    def __init__(self, parameters=None):
        super().__init__(parameters)

        # Load parameters
        self.protein_lengths = self.parameters['protein_lengths']
        self.translation_efficiencies = self.parameters[
            'translation_efficiencies']
        self.active_ribosome_fraction = self.parameters[
            'active_ribosome_fraction']
        self.ribosome_elongation_rates_dict = self.parameters[
            'elongation_rates']
        self.variable_elongation = self.parameters['variable_elongation']
        self.make_elongation_rates = self.parameters['make_elongation_rates']

        self.rna_id_to_cistron_indexes = self.parameters[
            'rna_id_to_cistron_indexes']
        self.cistron_start_end_pos_in_tu = self.parameters[
            'cistron_start_end_pos_in_tu']
        self.tu_ids = self.parameters['tu_ids']
        self.n_TUs = len(self.tu_ids)
        self.active_ribosome_footprint_size = self.parameters[
            'active_ribosome_footprint_size']

        # Get mapping from cistrons to protein monomers and TUs
        self.cistron_to_monomer_mapping = self.parameters[
            'cistron_to_monomer_mapping']
        self.cistron_tu_mapping_matrix = self.parameters[
            'cistron_tu_mapping_matrix']
        self.monomer_index_to_cistron_index = self.parameters[
            'monomer_index_to_cistron_index']
        self.monomer_index_to_tu_indexes = self.parameters[
            'monomer_index_to_tu_indexes']

        self.ribosome30S = self.parameters['ribosome30S']
        self.ribosome50S = self.parameters['ribosome50S']

        self.seed = self.parameters['seed']
        self.random_state = np.random.RandomState(seed = self.seed)
        # Use separate random state instance to create unique indices
        # so results are directly comparable with wcEcoli
        self.unique_idx_random_state = np.random.RandomState(seed=self.seed)

        self.empty_update = {
            'listeners': {
                'ribosome_data': {
                    'ribosomes_initialized': 0,
                    'prob_translation_per_transcript': 0.0}}}

        self.monomer_ids = self.parameters['monomer_ids']

        # Helper indices for Numpy indexing
        self.ribosome30S_idx = None

    def ports_schema(self):
        return {
            'environment': {
                'media_id': {
                    '_default': '',
                    '_updater': 'set'}},
            'listeners': {
                'ribosome_data': listener_schema({
                    'did_initialize': 0,
                    'target_prob_translation_per_transcript': (
                        [0] * len(self.monomer_ids), self.monomer_ids),
                    'actual_prob_translation_per_transcript': (
                        [0] * len(self.monomer_ids), self.monomer_ids),
                    'mRNA_is_overcrowded': ([False] * len(self.monomer_ids),
                        self.monomer_ids),
                    'ribosome_init_event_per_monomer': (
                        [0] * len(self.monomer_ids), self.monomer_ids),
                    'effective_elongation_rate': 0.0}),
            },
            'active_ribosome': numpy_schema('active_ribosome',
                emit=self.parameters['emit_unique']),
            'RNA': numpy_schema('RNAs',
                emit=self.parameters['emit_unique']),
            'bulk': numpy_schema('bulk'),
            'timestep': {'_default': self.parameters['time_step']}
        }

    def calculate_request(self, timestep, states):
        if self.ribosome30S_idx is None:
            bulk_ids = states['bulk']['id']
            self.ribosome30S_idx = bulk_name_to_idx(self.ribosome30S, bulk_ids)
            self.ribosome50S_idx = bulk_name_to_idx(self.ribosome50S, bulk_ids)

        current_media_id = states['environment']['media_id']

        # requests = {'subunits': states['subunits']}
        requests = {'bulk': [
            (self.ribosome30S_idx, counts(
                states['bulk'], self.ribosome30S_idx)),
            (self.ribosome50S_idx, counts(
                states['bulk'], self.ribosome50S_idx))
        ]}

        self.fracActiveRibosome = self.active_ribosome_fraction[
            current_media_id]

        # Read ribosome elongation rate from last timestep
        self.ribosomeElongationRate = states['listeners']['ribosome_data'][
            'effective_elongation_rate']
        # If the ribosome elongation rate is zero (which is always the case for
        # the first timestep), set ribosome elongation rate to the one in
        # dictionary
        if self.ribosomeElongationRate == 0:
            self.ribosomeElongationRate = self.ribosome_elongation_rates_dict[
                current_media_id].asNumber(units.aa / units.s)
        self.elongation_rates = self.make_elongation_rates(
            self.random_state,
            self.ribosomeElongationRate,
            1,  # want elongation rate, not lengths adjusted for time step
            self.variable_elongation)

        # Ensure rates are never zero
        self.elongation_rates = np.fmax(self.elongation_rates, 1)
        return requests

    def evolve_state(self, timestep, states):
        # Calculate number of ribosomes that could potentially be initialized
        # based on counts of free 30S and 50S subunits
        inactive_ribosome_count = np.min([
            counts(states['bulk'], self.ribosome30S_idx),
            counts(states['bulk'], self.ribosome50S_idx)
        ])

        # Calculate actual number of ribosomes that should be activated based
        # on probabilities
        (TU_index_RNAs, transcript_lengths, can_translate, is_full_transcript,
            unique_index_RNAs) = attrs(states['RNA'], ['TU_index',
                'transcript_length', 'can_translate', 'is_full_transcript',
                'unique_index'])
        TU_index_mRNAs = TU_index_RNAs[can_translate]
        length_mRNAs = transcript_lengths[can_translate]
        unique_index_mRNAs = unique_index_RNAs[can_translate]
        is_full_transcript_mRNAs = is_full_transcript[can_translate]
        is_incomplete_transcript_mRNAs = np.logical_not(
            is_full_transcript_mRNAs)

        # Calculate counts of each mRNA cistron from fully transcribed
        # transcription units
        TU_index_full_mRNAs = TU_index_mRNAs[is_full_transcript_mRNAs]
        TU_counts_full_mRNAs = np.bincount(
            TU_index_full_mRNAs, minlength=self.n_TUs)
        cistron_counts = self.cistron_tu_mapping_matrix.dot(
            TU_counts_full_mRNAs)

        # Calculate counts of each mRNA cistron from partially transcribed
        # transcription units
        TU_index_incomplete_mRNAs = TU_index_mRNAs[
            is_incomplete_transcript_mRNAs]
        length_incomplete_mRNAs = length_mRNAs[is_incomplete_transcript_mRNAs]

        for (TU_index, length) in zip(TU_index_incomplete_mRNAs,
                                      length_incomplete_mRNAs):
            cistron_indexes = self.rna_id_to_cistron_indexes(
                self.tu_ids[TU_index])
            cistron_start_positions = np.array([
                self.cistron_start_end_pos_in_tu[(cistron_index, TU_index)][0]
                for cistron_index in cistron_indexes
                ])

            cistron_counts[cistron_indexes] += length > cistron_start_positions

        # Calculate initiation probabilities for ribosomes based on mRNA counts
        # and associated mRNA translational efficiencies
        protein_init_prob = normalize(cistron_counts[
            self.cistron_to_monomer_mapping] * self.translation_efficiencies)
        target_protein_init_prob = protein_init_prob.copy()

        # Calculate actual number of ribosomes that should be activated based
        # on probabilities
        activation_prob = self.calculate_activation_prob(
            self.fracActiveRibosome,
            self.protein_lengths,
            self.elongation_rates,
            target_protein_init_prob,
            states['timestep'])

        n_ribosomes_to_activate = np.int64(activation_prob
            * inactive_ribosome_count)

        if n_ribosomes_to_activate == 0:
            update = dict(self.empty_update)
            update['active_ribosome'] = {}
            return self.empty_update

        # Cap the initiation probabilities at the maximum level physically
        # allowed from the known ribosome footprint sizes based on the
        # number of mRNAs
        max_p = (self.ribosomeElongationRate / self.active_ribosome_footprint_size
            * (units.s) * states['timestep'] /
            n_ribosomes_to_activate).asNumber()
        max_p_per_protein = max_p*cistron_counts[self.cistron_to_monomer_mapping]
        is_overcrowded = (protein_init_prob > max_p_per_protein)

        while np.any(protein_init_prob > max_p_per_protein):
            protein_init_prob[is_overcrowded] = max_p_per_protein[
                is_overcrowded]
            assert protein_init_prob[~is_overcrowded].sum() != 0
            scale_the_rest_by = (
                (1. - protein_init_prob[is_overcrowded].sum())
                / protein_init_prob[~is_overcrowded].sum()
                )
            protein_init_prob[~is_overcrowded] *= scale_the_rest_by
            is_overcrowded |= (protein_init_prob > max_p_per_protein)

        # Compute actual transcription probabilities of each transcript
        actual_protein_init_prob = protein_init_prob.copy()

        # Sample multinomial distribution to determine which mRNAs have full
        # 70S ribosomes initialized on them
        n_new_proteins = self.random_state.multinomial(
            n_ribosomes_to_activate,
            protein_init_prob)

        # Build attributes for active ribosomes.
        # Each ribosome is assigned a protein index for the protein that
        # corresponds to the polypeptide it will polymerize. This is done in
        # blocks of protein ids for efficiency.
        protein_indexes = np.empty(n_ribosomes_to_activate, np.int64)
        mRNA_indexes = np.empty(n_ribosomes_to_activate, np.int64)
        positions_on_mRNA = np.empty(n_ribosomes_to_activate, np.int64)
        nonzero_count = (n_new_proteins > 0)
        start_index = 0

        for protein_index, protein_counts in zip(
                np.arange(n_new_proteins.size)[nonzero_count],
                n_new_proteins[nonzero_count]):

            # Set protein index
            protein_indexes[start_index:start_index + protein_counts] = protein_index

            cistron_index = self.monomer_index_to_cistron_index[protein_index]

            attribute_indexes = []
            cistron_start_positions = []

            for TU_index in self.monomer_index_to_tu_indexes[protein_index]:
                attribute_indexes_this_TU = np.where(
                    TU_index_mRNAs == TU_index)[0]
                cistron_start_position = self.cistron_start_end_pos_in_tu[
                    (cistron_index, TU_index)][0]
                is_transcript_long_enough = (length_mRNAs[
                    attribute_indexes_this_TU] >= cistron_start_position)

                attribute_indexes.extend(attribute_indexes_this_TU[
                    is_transcript_long_enough])
                cistron_start_positions.extend([cistron_start_position] * len(
                    attribute_indexes_this_TU[is_transcript_long_enough]))

            n_mRNAs = len(attribute_indexes)

            # Distribute ribosomes among these mRNAs
            n_ribosomes_per_RNA = self.random_state.multinomial(
                protein_counts, np.full(n_mRNAs, 1. / n_mRNAs))

            # Get unique indexes of each mRNA
            mRNA_indexes[start_index:start_index + protein_counts] = np.repeat(
                unique_index_mRNAs[attribute_indexes], n_ribosomes_per_RNA)

            positions_on_mRNA[start_index:start_index + protein_counts] = np.repeat(
                cistron_start_positions, n_ribosomes_per_RNA
                )

            start_index += protein_counts

        # Create active 70S ribosomes and assign their attributes
        ribosome_indices = create_unique_indexes(
            n_ribosomes_to_activate, self.unique_idx_random_state)
        update = {
            'bulk': [
                (self.ribosome30S_idx, -n_new_proteins.sum()),
                (self.ribosome50S_idx, -n_new_proteins.sum())
            ],
            'active_ribosome': {
                'add': {
                    'unique_index': ribosome_indices,
                    'protein_index': protein_indexes,
                    'peptide_length': np.zeros(n_ribosomes_to_activate,
                                               dtype=np.int64),
                    'mRNA_index': mRNA_indexes,
                    'pos_on_mRNA': positions_on_mRNA
                },
            },
            'listeners': {
                'ribosome_data': {
                    'did_initialize': n_new_proteins.sum(),
                    'ribosome_init_event_per_monomer': n_new_proteins,
                    'target_prob_translation_per_transcript': target_protein_init_prob,
                    'actual_prob_translation_per_transcript': actual_protein_init_prob,
                    'mRNA_is_overcrowded': is_overcrowded}}}

        return update

    def calculate_activation_prob(
            self,
            fracActiveRibosome,
            proteinLengths,
            ribosomeElongationRates,
            proteinInitProb,
            timeStepSec):
        """
        Calculates the expected ribosome termination rate based on the ribosome
        elongation rate

        Args:
            allTranslationTimes: Vector of times required to translate each
                protein
            allTranslationTimestepCounts: Vector of numbers of timesteps
                required to translate each protein
            averageTranslationTimeStepCounts: Average number of timesteps
                required to translate a protein, weighted by initiation
                probabilities
            expectedTerminationRate: Average number of terminations in one
                timestep for one protein
        """
        allTranslationTimes = 1. / ribosomeElongationRates * proteinLengths
        allTranslationTimestepCounts = np.ceil(allTranslationTimes / timeStepSec)
        averageTranslationTimestepCounts = np.dot(allTranslationTimestepCounts, proteinInitProb)
        expectedTerminationRate = 1.0 / averageTranslationTimestepCounts

        # Modify given fraction of active ribosomes to take into account early
        # terminations in between timesteps
        # allFractionTimeInactive: Vector of probabilities an "active" ribosome
        #   will in effect be "inactive" because it has terminated during a
        #   timestep
        # averageFractionTimeInactive: Average probability of an "active"
        #   ribosome being in effect "inactive", weighted by initiation
        #   probabilities
        # effectiveFracActiveRnap: New higher "goal" for fraction of active
        #   ribosomes, considering that the "effective" fraction is lower than
        #   what the listener sees
        allFractionTimeInactive = 1 - allTranslationTimes / timeStepSec / allTranslationTimestepCounts
        averageFractionTimeInactive = np.dot(allFractionTimeInactive, proteinInitProb)
        effectiveFracActiveRibosome = fracActiveRibosome * 1 / (1 - averageFractionTimeInactive)

        # Return activation probability that will balance out the expected
        # termination rate
        activationProb = effectiveFracActiveRibosome * expectedTerminationRate / (1 - effectiveFracActiveRibosome)

        # The upper bound for the activation probability is temporarily set to
        # 1.0 to prevent negative molecule counts. This will lower the fraction
        # of active ribosomes for timesteps longer than roughly 1.8s.
        if activationProb >= 1.0:
            activationProb = 1

        return activationProb

def test_polypeptide_initiation():
    def make_elongation_rates(
            self,
            random,
            base,
            time_step,
            variable_elongation=False):
        return base

    all_mRNA_ids = ['wRNA', 'xRNA', 'yRNA', 'zRNA']
    protein_lengths = np.array([25, 9, 12, 29])
    test_config = {
        'protein_lengths': protein_lengths,
        'translation_efficiencies': normalize(np.array([0.1, 0.2, 0.3, 0.4])),
        'active_ribosome_fraction': {'minimal': 0.05},
        'variable_elongation': False,
        'make_elongation_rates': make_elongation_rates,
        'rna_id_to_cistron_indexes': lambda rna_id: all_mRNA_ids.index(rna_id),
        'cistron_start_end_pos_in_tu': {
            (idx, idx): (0, protein_length*3 + 3)
            for idx, protein_length in enumerate(protein_lengths)},
        'tu_ids': all_mRNA_ids,
        'cistron_to_monomer_mapping': np.arange(4),
        'cistron_tu_mapping_matrix': np.identity(4),
        'monomer_index_to_cistron_index': {i: i for i in range(4)},
        'monomer_index_to_tu_indexes': {i: (i,) for i in range(4)},
        'protein_index_to_TU_index': np.arange(4),
        'all_TU_ids': ['wRNA', 'xRNA', 'yRNA', 'zRNA'],
        'all_mRNA_ids': ['wRNA', 'xRNA', 'yRNA', 'zRNA'],
        'ribosome30S': '30S',
        'ribosome50S': '50S',
        'seed': 0}

    polypeptide_initiation = PolypeptideInitiation(test_config)

    state = {
        'environment': {
            'media_id': 'minimal'},
        'listeners': {
            'ribosome_data': {
                'effective_elongation_rate': 25}},
        'bulk': np.array([
            ('30S', 2000),
            ('50S', 3000),
        ], dtype=[('id', 'U40'), ('count', int)]),
        'RNA': np.array([
            (1, 0, True, 0, 103, True),
            (1, 0, True, 1, 103, True),
            (1, 1, True, 2, 39, True),
            (1, 2, True, 3, 51, True),
            (1, 2, True, 4, 51, True),
            (1, 3, True, 4, 119, True),
        ], dtype=[('_entryState', np.bool_), ('TU_index', int),
            ('can_translate', np.bool_), ('unique_index', int),
            ('transcript_length', int), ('is_full_transcript', np.bool_)])
    }

    settings = {
        'total_time': 10,
        'initial_state': state}

    data = simulate_process(polypeptide_initiation, settings)

    print(data)

if __name__ == "__main__":
    test_polypeptide_initiation()


#  Given a string s, find the length of the longest substring without repeating characters.

from collections import defaultdict

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """

        # Brute Force:

        # longest_sub = 0
        # len_s = len(s)
        # for index in range(len_s):
        #     letters_dict = defaultdict(int)
        #     cur_sub = 0
        #     for i in range(index, len_s):
        #         if letters_dict[s[i]] == 1:
        #             break
        #         letters_dict[s[i]] = 1
        #         cur_sub += 1
        #
        #     if cur_sub > longest_sub:
        #         longest_sub = cur_sub
        #
        # return longest_sub
        # ============================================
        # Sliding window:

        start, longest_sub = 0, 0
        len_s = len(s)
        letters_dict = defaultdict(int)

        for end in range(len_s):
            if s[end] in letters_dict:
                start = max(start, letters_dict[s[end]])

            longest_sub = max(longest_sub, end - start + 1)
            letters_dict[s[end]] = end + 1

        return longest_sub

if __name__ == '__main__':
    solution = Solution()
    s = "abcabcbb"
    # s = "bbbbb"
    # s = "pwwkew"
    # s = "abba"

    print(solution.lengthOfLongestSubstring(s))


import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**6)

def dfs(depth, cur, num_vow, num_con):
    if depth == L and num_vow >= 1 and num_con >= 2:
        print(''.join(ans))

    for i in range(cur, C):
        if not mark[i]:
            mark[i] = True
            ans.append(data[i])

            if data[i] in Vowels:
                dfs(depth+1, i+1, num_vow+1, num_con)
            else:
                dfs(depth+1, i+1, num_vow, num_con+1)

            ans.pop()
            mark[i] = False

if __name__ == "__main__":
    L, C    = map(int, input().split())
    data    = list(map(str, input().split()))
    data.sort()

    Vowels  = ['a', 'e', 'i', 'o', 'u']
    mark    = [False] * C
    ans     = []

    dfs(0, 0, 0, 0)


from flask import Flask
from flask_cors import CORS
import os

from . import config

from .app_blueprint import bp
import logging

__version__ = "0.2.12"

def create_app(test_config=None):
    app = Flask(__name__)
    CORS(app, expose_headers='WWW-Authenticate')

    configure_app(app)

    if test_config is not None:
        app.config.update(test_config)

    app.register_blueprint(bp)
    app.url_map.strict_slashes = False

    return app

def configure_app(app):

    # Load logging scheme from config.py
    app_settings = os.getenv('APP_SETTINGS')
    if not app_settings:
        app.config.from_object(config.BaseConfig)
    else:
        app.config.from_object(app_settings)

    # Configure logging
    # handler = logging.FileHandler(app.config['LOGGING_LOCATION'])
    # handler.setLevel(app.config['LOGGING_LEVEL'])
    # formatter = logging.Formatter(app.config['LOGGING_FORMAT'])
    # handler.setFormatter(formatter)
    # app.logger.addHandler(handler)


# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from sklearn.linear_model import Lasso
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

import os
print(os.listdir("../input"))

# Any results you write to the current directory are saved as output.
#read the training data
# train_df =  pd.read_csv('../input/train.csv', nrows = 10_000_000)
train_df =  pd.read_csv('../input/train.csv', nrows = 10_000_000)

train_df['pickup_datetime'] = train_df['pickup_datetime'].str.slice(0, 16)
train_df['pickup_datetime'] = pd.to_datetime(train_df['pickup_datetime'], utc=True, format='%Y-%m-%d %H:%M')
train_df.head()
train_df.loc[:,('dropoff_longitude','pickup_longitude')].head()
print(train_df.dropoff_longitude[:2])
print(train_df.isnull().sum())
train_df = train_df[train_df.fare_amount>=0]

#Remove NaN from dataset
print('Old size %d'% len(train_df))
train_df = train_df.dropna(how = 'any', axis = 'rows')
print('New size: %d' % len(train_df))
#change add_traval_vector_features to calculate distance using  Haversine
# def add_travel_vector_features(df):
#     df['abs_diff_longitude'] = (df.dropoff_longitude - df.pickup_longitude).abs()
#     df['abs_diff_latitude'] = (df.dropoff_latitude - df.pickup_latitude).abs()

# add_travel_vector_features(train_df)
def distance(df):
    p = 0.017453292519943295     #Pi/180
    a = 0.5 - np.cos((df.dropoff_latitude - df.pickup_latitude) * p)/2 + np.cos(df.pickup_latitude * p) * np.cos(df.dropoff_latitude * p) * (1 - np.cos((df.dropoff_longitude - df.pickup_longitude) * p)) / 2
#     return 12742 * asin(sqrt(a)) #2*R*asin...
    df['distance_miles'] = 0.6213712 * 12742 * np.arcsin(np.sqrt(a))
distance(train_df)
# plot = train_df.iloc[:2000].plot.scatter('abs_diff_longitude', 'abs_diff_latitude')
# print('Old size: %d' % len(train_df))
# train_df = train_df[(train_df.abs_diff_longitude < 5.0) & (train_df.abs_diff_latitude < 5.0)]
# print('New size: %d' % len(train_df))
train_df = train_df[(train_df.distance_miles < 345)]

# Removing observations with erroneous values
mask = train_df['pickup_longitude'].between(-75, -73)
mask &= train_df['dropoff_longitude'].between(-75, -73)
mask &= train_df['pickup_latitude'].between(40, 42)
mask &= train_df['dropoff_latitude'].between(40, 42)
mask &= train_df['passenger_count'].between(0, 8)
mask &= train_df['fare_amount'].between(0, 250)

train_df = train_df[mask]

train_df['hour'] = train_df.pickup_datetime.apply(lambda t: pd.to_datetime(t).hour)
train_df['year'] = train_df.pickup_datetime.apply(lambda t: pd.to_datetime(t).year)
# Get input matrix
def get_input_matrix(df):
    return np.column_stack((df.year,df.hour,df.distance_miles,df.passenger_count, np.ones(len(df))))

#X_train= get_input_matrix(train_df)
#y_train = np.array(train_df['fare_amount'])

#print(X_train.shape)
#print(y_train.shape)
X = get_input_matrix(train_df)
y = np.array(train_df['fare_amount'])

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score

# Create training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=42)
# Create the regressor: reg_all
reg_all = LinearRegression()
cv_scores = cross_val_score(reg_all,X,y,cv=5)
# Fit the regressor to the training data
reg_all.fit(X_train, y_train)
# Predict on the test data: y_pred
y_pred = reg_all.predict(X_test)

print("R^2: {}".format(reg_all.score(X_test, y_test)))
rmse = np.sqrt(mean_squared_error(y_test , y_pred))
print("Root Mean Squared Error: {}".format(rmse))

# Print the 5-fold cross-validation scores
print(cv_scores)

print("Average 5-Fold CV Score: {}".format(np.mean(cv_scores)))

train_df.columns.values
df_columns = pd.Index([  'pickup_longitude',
       'pickup_latitude', 'dropoff_longitude', 'dropoff_latitude',
       'passenger_count', 'distance_miles','hour','year'])
df_columns
#Find the most important variable
# Instantiate a lasso regressor: lasso
X_all_feature = np.column_stack((train_df.pickup_longitude,train_df.pickup_latitude,train_df.dropoff_longitude,
                    train_df.dropoff_latitude,train_df.passenger_count,train_df.distance_miles,train_df.hour,train_df.year))
X_all_feature
lasso = Lasso(alpha=0.1)

# Fit the regressor to the data
lasso.fit(X_all_feature,y)

# Compute and print the coefficients
lasso_coef = lasso.coef_
print(lasso_coef)

# Plot the coefficients
plt.plot(range(len(df_columns)), lasso_coef)
plt.xticks(range(len(df_columns)), df_columns.values, rotation=60)
plt.margins(0.02)
plt.show()
test_df = pd.read_csv('../input/test.csv')
test_df.dtypes
# Reuse the above helper functions to add our features and generate the input matrix.
# add_travel_vector_features(test_df)
distance(test_df)
test_df['hour'] = test_df.pickup_datetime.apply(lambda t: pd.to_datetime(t).hour)
test_df['year'] = test_df.pickup_datetime.apply(lambda t: pd.to_datetime(t).year)
test_X = get_input_matrix(test_df)

# Predict fare_amount on the test set using our model (w) trained on the training set.
# test_y_predictions = np.matmul(test_X, w_OLS).round(decimals = 2)
test_y_predictions = reg_all.predict(test_X)
test_y_predictions

# Write the predictions to a CSV file which we can submit to the competition.
submission = pd.DataFrame(
    {'key': test_df.key, 'fare_amount': test_y_predictions},
    columns = ['key', 'fare_amount'])
submission.to_csv('submission.csv', index = False)

print(os.listdir('.'))
test_y_predictions[:200]
data = pd.read_csv('submission.csv')
data


"""
トポロジカルソート:与えられた有向グラフに対し、各頂点を辺の向きに沿うように順序をつけて並び替える。
＊有向グラフGが有向サイクルを含まないことが必要十分条件(DAG)
＊トポロジカルソート順は一意でなく、複数通り存在する
＊再帰関数を使用した深さ優先探索をする
"""
"""
各頂点v ∈ Vについて
再帰関数dfs(G, v)が呼ばれる瞬間(行きがけ順)：v-in
再帰関数dfs(G, v)を終了する瞬間(帰りがけ順)：v-out
と表す
"""
"""
考え方
深さ優先探索における再帰関数を抜けた順序に頂点を並べ、それを逆順に並べる
→トポロジカルソート順が得られる
"""
#トポロジカルソートをする
def rec(g, v):
    seen[v] = True
    for next_v in g[v]:
        if seen[next_v]:
            continue
        rec(g, next_v)
    #v-outを記憶する
    order.append(v)

n, m = map(int, input().split()) #頂点数と枝数
g = [[] for _ in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    g[a].append(b)

#探索
seen = [False] * n
order = [] #トポロジカルソート順を表す
for v in range(n):
    if seen[v]:
        continue
    rec(g, v)
order.reverse()

for v in order:
    print(str(v) + " -> ", end = "")
print("")


import os
from unicodedata import normalize

import numpy as np
from LSC_recognizer_model.src.dinamic.utils.video_utils import (
    change_fps_of_video,
    predict_video_seconds_dict,
    save_video_change_fps,
)

def generate_npy_files_from_video(
    filename,
    holistic,
    save_path_numpy: str = "",
    save_path_video_detection_draw: str = "",
    fps_expected=20,
):
    save_videos = save_path_video_detection_draw != ""
    save_results = save_path_numpy != ""

    try:
        # Process the video
        dict_seconds, width, height = change_fps_of_video(filename=filename, fps_expected=fps_expected)

        video_coords = predict_video_seconds_dict(
            holistic=holistic,
            seconds=dict_seconds,
            fps=fps_expected,
            used_parts=["pose", "right_hand", "left_hand", "face"],
        )

        # Get names of file
        signal_name = filename.split("/")[-2]  # Get the name of the signal
        video_name = filename.split("/")[-1]  # Get the name of the image
        video_name = video_name.split(".")[0]  # Remove the extension of the image
        video_name = video_name.split("_")[0]  # Remove the state of the image ej: 10_notprocessed.mp4

        # Delete from the name some characters that can cause problems
        trans_tab = dict.fromkeys(map(ord, "\u0301\u0308"), None)
        signal_name = normalize("NFKC", normalize("NFKD", signal_name).translate(trans_tab))
        video_name = normalize("NFKC", normalize("NFKD", video_name).translate(trans_tab))

        if save_videos:
            save_path = f"{save_path_video_detection_draw}/{signal_name}"
            save_video_change_fps(
                seconds_dict=dict_seconds,
                fps=fps_expected,
                save_path=save_path,
                video_name=video_name,
                width=width,
                height=height,
            )

        if save_results:
            array_to_save = np.array(video_coords, dtype=object)
            save_coordenates(
                coordenates=array_to_save,
                path=save_path_numpy,
                signal_name=signal_name,
                name=video_name,
            )

        return video_coords

    except Exception as error:
        print(f"Error con el video {filename}: {error}")
        return None

def save_coordenates(coordenates, path, signal_name, name):
    # Create folder if not exists
    folder = path + "/" + signal_name
    if not os.path.exists(folder):
        os.makedirs(folder)

    # Save coordenates
    with open(f"{path}/{signal_name}/{name}.npy", "wb") as f:
        np.save(f, coordenates)


from django.views.decorators.http import require_http_methods
from django.http import JsonResponse
from common.json import ModelEncoder
import json
from .models import InvVO, Technician, ServiceAppointment

class InvVOEncoder(ModelEncoder):
    model = InvVO
    properties = [
        "VINVO", "VIP",
    ]

class TechnicianEncoder(ModelEncoder):
    model = Technician
    properties = [
        "name", "employee_number",
    ]

class ServiceAppointmentEncoder(ModelEncoder):
    model = ServiceAppointment
    properties = [
        "id", "date", "service_reason", "owner", "completed",
        "VIN", "technician",
    ]
    encoders = {
        "VIN": InvVOEncoder(),
        "technician": TechnicianEncoder()
    }

@require_http_methods(["GET", "POST"])
def api_list_service_appointments(request):
    if request.method == "GET":
        appointments = ServiceAppointment.objects.all()
        return JsonResponse({"appointments": appointments}, encoder=ServiceAppointmentEncoder, safe=False)
    else:
        content = json.loads(request.body)

        try:
            vinvo = content["VIN"]
            vin = InvVO.objects.get(VINVO=vinvo)
            content["VIN"] = vin
        except InvVO.DoesNotExist:
            vin = InvVO.objects.create(VINVO=content["VIN"])
            content["VIN"] = vin

        try:
            employee_number = content["technician"]
            technician = Technician.objects.get(employee_number=employee_number)
            content["technician"] = technician
        except Technician.DoesNotExist:
            return JsonResponse({"Message": "Invalid employee ID"})

        appointment = ServiceAppointment.objects.create(**content)
        return JsonResponse(appointment, encoder=ServiceAppointmentEncoder, safe=False)

@require_http_methods(["GET", "DELETE", "PUT"])
def api_detail_service_appointment(request, pk):
    if request.method == "GET":
        service = ServiceAppointment.objects.filter(id=pk)
        return JsonResponse({"appointment": service}, encoder=ServiceAppointmentEncoder, safe=False)
    elif request.method == "DELETE":
        count, _ = ServiceAppointment.objects.filter(id=pk).delete()
        return JsonResponse({"deleted": count > 0})
    else:
        content = json.loads(request.body)

        ServiceAppointment.objects.filter(id=pk).update(**content)
        appointment = ServiceAppointment.objects.get(id=pk)
        return JsonResponse({"appointment": appointment}, encoder=ServiceAppointmentEncoder, safe=False)

@require_http_methods(["GET", "POST"])
def api_list_techs(request):
    if request.method == "GET":
        technicians = Technician.objects.all()
        return JsonResponse({"technicians": technicians}, encoder=TechnicianEncoder, safe=False)
    else:
        content = json.loads(request.body)
        technician = Technician.objects.create(**content)
        return JsonResponse(technician, encoder=TechnicianEncoder, safe=False)

@require_http_methods(["DELETE"])
def api_detail_techs(request, num):
    count, _ = Technician.objects.filter(employee_number=num).delete()
    return JsonResponse({"Deleted": count > 0})


import math
import numpy as np

BEACON_CODE = 1
TIME = 1
FUSED_TRACK_ID = 21
TRACK_TYPE = 22

SYSTEM_TRACK = 2

def UASReadOutput( filename ) :
    file = open( filename, 'r' )
    data = []
    for line in file :
        if len( line ) > 1 :
            line = line.strip()
            columns = line.split( "," )
            columns = [ float( x ) for x in columns ]
            if columns[ TRACK_TYPE ] == SYSTEM_TRACK :
                data.append( columns )
    file.close()
    data = np.array( data )
    tracks = np.unique( data[ :, FUSED_TRACK_ID ] )
    tracks = np.delete( tracks, [ 0 ] )
    return ( data, tracks )


from tkinter import Tk, NW, ALL, Canvas, PhotoImage

def init(data):
    data.step = 0
    loadPlayingCardImages(data)  # always load images in init!

def loadPlayingCardImages(data):
    cards = 55  # cards 1-52, back, joker1, joker2
    data.cardImages = []
    for card in range(cards):
        rank = (card % 13)+1
        suit = "cdhsx"[card//13]
        filename = "playing-card-gifs/%s%d.gif" % (suit, rank)
        data.cardImages.append(PhotoImage(file=filename))

def getPlayingCardImage(data, rank, suitName):
    suitName = suitName[0].lower()  # only car about first letter
    suitNames = "cdhsx"
    assert(1 <= rank <= 13)
    assert(suitName in suitNames)
    suit = suitNames.index(suitName)
    return data.cardImages[13*suit + rank - 1]

def getSpecialPlayingCardImage(data, name):
    specialNames = ["back", "joker1", "joker2"]
    return getPlayingCardImage(data, specialNames.index(name)+1, "x")

def mousePressed(event, data):
    pass

def keyPressed(event, data):
    pass

def timerFired(data):
    data.step += 1

def redrawAll(canvas, data):
    suitNames = ["Clubs", "Diamonds", "Hearts", "Spades", "Xtras"]
    suit = (data.step//10) % len(suitNames)
    suitName = suitNames[suit]
    cards = 3 if (suitName == "Xtras") else 13
    margin = 10
    (left, top) = (margin, 40)
    for rank in range(1, cards+1):
        image = getPlayingCardImage(data, rank, suitName)
        if (left + image.width() > data.width):
            (left, top) = (margin, top + image.height() + margin)
        canvas.create_image(left, top, anchor=NW, image=image)
        left += image.width() + margin
    canvas.create_text(data.width/2, 20, text=suitName, font="Arial 28 bold")

# use the run function as-is
def run(width=300, height=300):
    def redrawAllWrapper(canvas, data):
        canvas.delete(ALL)
        canvas.create_rectangle(0, 0, data.width, data.height,
                                fill='white', width=0)
        redrawAll(canvas, data)
        canvas.update()

    def mousePressedWrapper(event, canvas, data):
        mousePressed(event, data)
        redrawAllWrapper(canvas, data)

    def keyPressedWrapper(event, canvas, data):
        keyPressed(event, data)
        redrawAllWrapper(canvas, data)

    def timerFiredWrapper(canvas, data):
        timerFired(data)
        redrawAllWrapper(canvas, data)
        # pause, then call timerFired again
        canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
    # Create root before calling init (so we can create images in init)
    root = Tk()
    # Set up data and call init

    class Struct(object):
        pass
    data = Struct()
    data.width = width
    data.height = height
    data.timerDelay = 250  # milliseconds
    init(data)
    # create the root and the canvas
    canvas = Canvas(root, width=data.width, height=data.height)
    canvas.pack()
    # set up events
    root.bind("<Button-1>", lambda event:
              mousePressedWrapper(event, canvas, data))
    root.bind("<Key>", lambda event:
              keyPressedWrapper(event, canvas, data))
    timerFiredWrapper(canvas, data)
    # and launch the app
    root.mainloop()  # blocks until window is closed
    print("bye!")

run(420, 360)


from torch import nn, einsum
import torch
from functools import partial

from src.models.helpers import exists, default, PreNorm, SinusoidalPositionEmbeddings, Residual
from src.models.conv_blocks import ResnetBlock, Downsample, Upsample
from src.models.attention import Attention, LinearAttention

from src.train.util import partial_load_model

class Unet(nn.Module):
    def __init__(
        self,
        img_size,
        init_dim = None,
        dim_mults = (1, 2, 4, 8),
        time_dim = None,
        in_channels = 3,
        out_channels = 3,
        down_mode = 'avg',
        down_kern = 2,
        up_mode = 'nearest',
        up_scale = 2,
        resnet_stacks = 2,
        attn_heads = 4,
        attn_head_res = 32,
        self_condition = False,
        resnet_grnorm_groups = 4,
        classes = None
    ):
        """
        img_size             - assuming square image of (img_size, img_size)
        init_dim             - out planes from the pre-Unet layer (i.e. in_channels -> init_dim)
        dim_mults            - tuple of multipliers to multiply element-wise init_dim,
        time_dim             - dimensinality of time embeddings, if None: 4*img_size
        in_channels          - number of input channels
        out_channels         - number of output channels of the UNet
        self_condition       - legace from Hugging Face implenetation. IDK
        resnet_grnorm_groups - numbers for group norm for each  ResNet blocks
        resnet_stacks        - number of ResNet blocks
        classes              - number of classes or list of integers for number of classes for each label/type
        down_mode:           - if "conv", then strided convolution is used,
                             "avg" ot "max" - average2D or maxPool2D are used respectively
        down_kern:           - Size of the pooling kernel, has effect only if down_mode is avg or max
        up_mode:             - If 'conv", strided transposed convolution is used, otherwise, interpolation
        up_scale             - Upscale interpolation factor, default 2

        Adopted from: https://huggingface.co/blog/annotated-diffusion with modifications:
        - module lists init
        - replaced mid-attention with linear attention
        - added class conditions
        - replaced 'manual' down and up with a for-loop
        """
        super().__init__()

        # determine dimensions
        if not out_channels:
            out_channels = in_channels
        self.self_condition = self_condition
        input_channels = in_channels * (2 if self_condition else 1)
        init_dim = init_dim if init_dim else img_size
        dims = [init_dim, *map(lambda m: init_dim * m, dim_mults)]
        in_out = list(zip(dims[:-1], dims[1:]))
        self.resnet_stacks = resnet_stacks

        # time embeddings
        if not time_dim:
            time_dim = img_size * 4

        self.init_conv = nn.Conv2d(input_channels, init_dim, 1, padding = 0)
        conv_unit = partial(ResnetBlock, groups=resnet_grnorm_groups)

        self.time_mlp = nn.Sequential(
            SinusoidalPositionEmbeddings(img_size),
            nn.Linear(img_size, time_dim),
            nn.GELU(),
            nn.Linear(time_dim, time_dim),
        )

        # layers
        self.downs = nn.ModuleList([])
        self.ups = nn.ModuleList([])
        num_resolutions = len(in_out)

        # Down
        for ind, (dim_in, dim_out) in enumerate(in_out):
            is_last = ind >= (num_resolutions - 1)

            self.downs.append(
                nn.ModuleList([conv_unit(dim_in, dim_in, time_emb_dim=time_dim) for _ in range(self.resnet_stacks)])
                +
                nn.ModuleList(
                    [
                        Residual(PreNorm(dim_in, LinearAttention(dim = dim_in, heads=attn_heads, dim_head=attn_head_res))),
                        Downsample(dim_in, dim_out, down_mode, down_kern)
                        if not is_last
                        else nn.Conv2d(dim_in, dim_out, 3, padding=1),
                    ]
                )
            )

        mid_dim = dims[-1]
        self.mid_block1 = conv_unit(mid_dim, mid_dim, time_emb_dim=time_dim)
        self.mid_attn = Residual(PreNorm(mid_dim, Attention(dim=mid_dim, heads=attn_heads, dim_head=attn_head_res))) # replaced with Linear attention
        #self.mid_attn = Residual(PreNorm(mid_dim, LinearAttention(dim = mid_dim, heads=attn_heads, dim_head=attn_head_res)))
        self.mid_block2 = conv_unit(mid_dim, mid_dim, time_emb_dim=time_dim)

        # Up
        for ind, (dim_in, dim_out) in enumerate(reversed(in_out)):
            is_last = ind == (len(in_out) - 1)

            self.ups.append(
                nn.ModuleList([conv_unit(dim_out + dim_in, dim_out, time_emb_dim=time_dim) for _ in range(self.resnet_stacks)])
                +
                nn.ModuleList(
                    [
                        Residual(PreNorm(dim_out, LinearAttention(dim=dim_out, heads=attn_heads, dim_head=attn_head_res))),
                        Upsample(dim_out, dim_in, up_mode, up_scale)
                        if not is_last
                        else nn.Conv2d(dim_out, dim_in, 3, padding=1),
                    ]
                )
            )

        self.final_res_block = conv_unit(dim_in*2, img_size, time_emb_dim=time_dim) # dim * 2
        self.final_conv = nn.Conv2d(img_size, out_channels, 1)

        if classes:
            if type(classes) == int:
                self.classes = [classes]
            else:
                self.classes = classes
            # nn.Embeddings are commented out for now
            # the new approach with MLP should be flexible
            # when multi-class labels are supplied
            #self.lbl_embeds = nn.Embedding(classes, time_dim)
            self.lbl_embeds = nn.Sequential(*[
                nn.Linear(len(self.classes), time_dim),
                nn.GELU(),
                nn.Linear(time_dim, time_dim)
            ])

    def forward(self, x, time, x_self_cond=None, lbls = None):
        if self.self_condition:
            x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x))
            x = torch.cat((x_self_cond, x), dim=1)

        x = self.init_conv(x)
        r = x.clone()

        t = self.time_mlp(time)

        if lbls is not None:
            t += self.lbl_embeds(lbls)

        h = []

        # downwards descent
        for i, layer in enumerate(self.downs):
            # iterate over resnet blocks
            for block in layer[0:self.resnet_stacks]:
                x = block(x,t)
                h.append(x)
            # attention
            x = layer[self.resnet_stacks](x)
            # downsampler
            x = layer[-1](x)

        x = self.mid_block1(x, t)
        x = self.mid_attn(x)
        x = self.mid_block2(x, t)

        # upwards ascent
        for i, layer in enumerate(self.ups):
            # iterate over resnet blocks
            for bi, block in enumerate(layer[0:self.resnet_stacks]):
                x_down = h.pop()
                x = torch.cat((x,  x_down), dim=1)
                x = block(x,t)
            # attention
            x = layer[self.resnet_stacks](x)
            # upsampler
            x = layer[-1](x)

        x = torch.cat((x, r), dim=1)

        x = self.final_res_block(x, t)
        return self.final_conv(x)
# ----------------------------------------------------------------------------------------

def set_unet(config_dict):
    img_size             = config_dict['img_size']
    init_dim             = config_dict.pop('init_dim', None)
    dim_mults            = config_dict.pop('dim_mults', (1, 2, 4, 8))
    time_dim             = config_dict.pop('time_dim', None)
    in_channels          = config_dict.pop('in_channels', 3)
    out_channels         = config_dict.pop('out_channels', 3)
    self_condition       = config_dict.pop('self_condition', False)
    resnet_grnorm_groups = config_dict.pop('resnet_grnorm_groups', 4)
    resnet_stacks        = config_dict.pop('resnet_stacks', 2)
    classes              = config_dict.pop('classes', None)
    down_mode            = config_dict.pop('classes', 'avg')
    down_kern            = config_dict.pop('down_kern', 2)
    up_mode              = config_dict.pop('up_mode', 'bilinear')
    up_scale             = config_dict.pop('up_scale', 2)
    attn_heads           = config_dict.pop('attn_heads', 4)
    attn_head_res        = config_dict.pop('attn_head_res', 16)

    model = Unet(
        img_size             = img_size,
        init_dim             = init_dim,
        dim_mults            = dim_mults,
        time_dim             = time_dim,
        in_channels          = in_channels,
        out_channels         = out_channels,
        self_condition       = self_condition,
        resnet_grnorm_groups = resnet_grnorm_groups,
        resnet_stacks        = resnet_stacks,
        classes              = classes,
        down_mode            = down_mode,
        down_kern            = down_kern,
        up_mode              = up_mode,
        up_scale             = up_scale,
        attn_heads           = attn_heads,
        attn_head_res        = attn_head_res
    )

    if 'load_name' in config_dict:
        weights = config_dict['load_name']
    else:
        weights = None

    if weights:
        print(f'Loading model weights from\n\t{weights}')
        model = partial_load_model(model, weights)

    return model


"""Added complain table

Revision ID: 485543c154fc
Revises: c6d2d23080c5
Create Date: 2022-11-03 11:14:20.799902

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '485543c154fc'
down_revision = 'c6d2d23080c5'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('complain',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('firstname', sa.String(length=20), nullable=False),
    sa.Column('lastname', sa.String(length=200), nullable=False),
    sa.Column('complain', sa.Text(length=500), nullable=False),
    sa.Column('date_of_complain', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('complain')
    # ### end Alembic commands ###


import encoding
import bitwise
import calculation
import decrypt
import encrypt

#print("Set 1 - Challenge 1")
#print(encoding.hex_to_text('49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d'))
#
#print("\n")
#print("Set 1 - Challenge 2")
#str1 = encoding.hex_to_binary("1c0111001f010100061a024b53535009181c")
#str2 = encoding.hex_to_binary("686974207468652062756c6c277320657965")
#bin_text = bitwise.xor_two_bit_string(str1, str2)
#print(encoding.binary_to_hex(bin_text))
#
#print("\n")
#print("Set 1 - Challenge 3")
#print(decrypt.xor_single_hex("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"))
#
#print("\n")
#print("Set 1 -- Challenge 4")
### download from https://cryptopals.com/static/challenge-data/4.txt
#file_set1_challenge4 = open("files/set1-challenge4.txt")
#content_set1_challenge4 = file_set1_challenge4.read()
#for line in content_set1_challenge4.splitlines():
#    decoded_text = decrypt.xor_single_hex(line)
#    score_decoded_text = calculation.character_frequency_score(decoded_text)
#    if score_decoded_text > 4:
#        print(decoded_text) # look like the plain text is "Now that the party is jumping" :)))
#
#print("\n")
#print("Set 1 --  Challenge 5")
#file_set1_challenge5 = open("files/set1-challenge5.txt")
#content_set1_challenge5 = file_set1_challenge5.read()
#key_set1_challenge5 = "ICE"
#cipher_set1_challenge5 = encrypt.repeating_xor_key(content_set1_challenge5, key_set1_challenge5)
#print(encoding.text_to_hex(cipher_set1_challenge5))

print("\n")
print("Set 1 -- Chanllenge 6")
file_set1_challenge6 = open("files/set1-challenge6.txt")
content_set1_challenge6_base64 = file_set1_challenge6.read()
content_set1_challenge6 = encoding.decode_base64_to_text(content_set1_challenge6_base64)
length_of_the_key = -1
smallest_normalized = 99999
# KEYSIZE from 2 to 40
for i in range(2, 41):
    text11 = content_set1_challenge6[i:2*i]
    text12 = content_set1_challenge6[2*i:2*i+i]
    hs1 = calculation.hamming_distance_2text(text11, text12)

    text21 = content_set1_challenge6[3*i:3*i+i]
    text22 = content_set1_challenge6[4*i:4*i+i]
    hs2 = calculation.hamming_distance_2text(text21, text22)

    text31 = content_set1_challenge6[6*i:6*i+i]
    text32 = content_set1_challenge6[7*i:7*i+i]
    hs3 = calculation.hamming_distance_2text(text31, text32)

    avg_normalized = (hs1 + hs2 + hs3)/(3*i)
    if avg_normalized < smallest_normalized:
        smallest_normalized = avg_normalized
        length_of_the_key = i

block_dictionary = {}
for i in range(0, len(content_set1_challenge6), length_of_the_key):
    to_index = i + length_of_the_key
    if to_index > len(content_set1_challenge6):
        to_index = len(content_set1_challenge6)
    block = content_set1_challenge6[i:to_index]
    for i in range(0, len(block)):
        if i in block_dictionary:
            block_dictionary[i] = block_dictionary[i] + block[i]
        else:
            block_dictionary[i] = block[i]

key = ""
for item in block_dictionary:
    key = key + decrypt.break_single_key_xor(block_dictionary[item])

# suprise it worked :)) with stupid cacl score by counting spaces(character_frequency_score function). lmao
# the key is "Terminator X: Bring the noise"
print(key)


import altair as alt
import pandas as pd

def altair_scatter_plot(df: pd.DataFrame) -> alt.vegalite.v4.api.Chart:

    base_options = list(df['artist_name'].unique())
    base_options.sort()
    options = [None] + base_options
    options_labels = ['All artists'] + base_options
    input_dropdown = alt.binding_select(options=options,
                                        labels=options_labels,
                                        name=' ')

    selector = alt.selection_single(empty='all', fields=['artist_name'])
    dropdown = alt.selection_single(fields=['artist_name'],
                                    bind=input_dropdown)
    scaler = alt.selection_interval(bind='scales')

    scatter = alt.Chart(df)\
                 .mark_circle(size=150,
                              smooth=True,
                              color="#1DB954",
                              stroke='#1f1e1e',
                              strokeWidth=1)\
                 .encode(alt.X('duration_min',
                               title='Duration (Min)'),
                         alt.Y('popularity',
                               title='Popularity',
                               scale=alt.Scale(domain=[0, 100])),
                         opacity=alt.condition(dropdown & selector,
                                               alt.value(1),
                                               alt.value(0.05)),
                         tooltip=[alt.Tooltip('track_name', title='Track'),
                                  alt.Tooltip('artist_name', title='Artist'),
                                  alt.Tooltip('duration_min', title='Duration (min)'),
                                  alt.Tooltip('popularity', title='Popularity')])\
                 .properties(height=350,
                             width=500)\
                 .configure_axis(titleFontSize=16,
                                 labelFontSize=13,
                                 labelFont='Helvetica')\
                 .configure_title(font='Helvetica')\
                 .add_selection(dropdown,
                                scaler,
                                selector)

    return scatter


import tweepy
import time

auth = tweepy.OAuth1UserHandler(
   '7POHEsJv6mrw668KcNTcyKmPs', '17a9opR34yX4YeJ2wnVSXkpyxev1liT8jmbPG4weMLCxDIamXn', '1597932774253809665-vX7OmjMr07p1OrMnpJgCDv3M7bP33G', 'cEnXNZjnZ1KErGsTOCYgWqjv7qo0lAzzFrrKftpkCY1zJ'
)

api = tweepy.API(auth, wait_on_rate_limit=True)

for follower in tweepy.Cursor(api.get_followers).items():
   api.create_friendship(screen_name=follower.screen_name)

search_string = "Day #100DaysOfCode"
tweets_limit = 50

for tweet in tweepy.Cursor(api.search_tweets , search_string).items(tweets_limit):
         try:
            api.create_favorite(tweet.id)
            api.retweet(tweet.id)
            print("tweet liked")
            time.sleep(10)
         except tweepy.TweepyException as e:
            print(e)
            if '429' in str(e):
               time.sleep(6000)
         except StopIteration:
            break


from __future__ import print_function
import base64, binascii, calendar, collections, copy, os.path, random, socket, string, struct, textwrap, time
from itertools import chain

from pdns.bit import get_bits, set_bits
from pdns.bimap import Bimap, BimapError
from pdns.buffer import Buffer, BufferError

try:
    from itertools import zip_longest
except ImportError:
    from itertools import izip_longest as zip_longest

class DNSError(Exception):
    pass

# DNS codes

QTYPE = Bimap(
    'QTYPE',
    {1: 'A',
     2: 'NS',
     5: 'CNAME',
     6: 'SOA',
     12: 'PTR',
     15: 'MX',
     16: 'TXT',
     17: 'RP',
     18: 'AFSDB',
     24: 'SIG',
     25: 'KEY',
     28: 'AAAA',
     29: 'LOC',
     33: 'SRV',
     35: 'NAPTR',
     36: 'KX',
     37: 'CERT',
     38: 'A6',
     39: 'DNAME',
     41: 'OPT',
     42: 'APL',
     43: 'DS',
     44: 'SSHFP',
     45: 'IPSECKEY',
     46: 'RRSIG',
     47: 'NSEC',
     48: 'DNSKEY',
     49: 'DHCID',
     50: 'NSEC3',
     51: 'NSEC3PARAM',
     52: 'TLSA',
     55: 'HIP',
     99: 'SPF',
     249: 'TKEY',
     250: 'TSIG',
     251: 'IXFR',
     252: 'AXFR',
     255: 'ANY',
     257: 'CAA',
     32768: 'TA',
     32769: 'DLV'}, DNSError)

CLASS = Bimap(
    'CLASS',
    {1: 'IN',
     2: 'CS',
     3: 'CH',
     4: 'Hesiod',
     254: 'None',
     255: '*'}, DNSError)

QR = Bimap(
    'QR',
    {0: 'QUERY',
     1: 'RESPONSE'}, DNSError)

RCODE = Bimap(
    'RCODE',
    {0: 'NOERROR',
     1: 'FORMERR',
     2: 'SERVFAIL',
     3: 'NXDOMAIN',
     4: 'NOTIMP',
     5: 'REFUSED',
     6: 'YXDOMAIN',
     7: 'YXRRSET',
     8: 'NXRRSET',
     9: 'NOTAUTH',
     10: 'NOTZONE'},
    DNSError)

OPCODE = Bimap(
    'OPCODE',
    {0: 'QUERY',
     1: 'IQUERY',
     2: 'STATUS',
     5: 'UPDATE'},
    DNSError)

def label(label, origin=None):
    if label.endswith('.'):
        return DNSLabel(label)
    else:
        return (origin if isinstance(origin, DNSLabel) else DNSLabel(origin)).add(label)


from flask import Flask, render_template, request
from services.process import calculate

app = Flask(__name__, template_folder="templates",
            static_folder='static')
app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/result', methods=['get'])
def process():
    mode = request.args.get('mode')
    hour = request.args.get('hour')
    minutes = request.args.get('minutes')

    timesAdviced = calculate(mode, hour, minutes)
    print(timesAdviced)
    return render_template("result.html", mode=mode, timesAdviced=timesAdviced)

if __name__ == '__main__':
    app.run()


from bs4 import BeautifulSoup
import re
import requests

def get_joke():
    url = "https://icanhazdadjoke.com/"
    reading = requests.get(url)
    soup = BeautifulSoup(reading.text, "lxml")
    # print(reading.text)
    spans = soup.find_all('div', {'class': "card-content"})
    # print(spans)
    return spans[0].find("p").get_text()
    # re.sub('[^a-zA-Z]+', '', spans[0].find("p").get_text())
    # for s in spans:
    #    print(s.get_text())

def main():
    print(get_joke())

if __name__ == "__main__":
    main()


# Escreva um programa que pergunte a quantidade de Km percorridos por um carro alugado
# e a quantidade de dias pelos quais ele foi alugado. Calcule o preço a pagar, sabendo
# que o carro custa R$60 por dia e R$0,15 por Km rodado.

qdadeKM = float(input('Informe a quantidade de Km percorridos:'))
qdadeDias = int(input('Informe a quantidade de Dias:'))

diaria = 60
valorKM = .15

valor = qdadeDias * diaria + qdadeKM * valorKM
print('O valor a pagar é:', valor)

# print("Esse é o preço antigo:", preço)
# print("Esse é o preço novo:", preçoNovo)
# print("O preço antes do desconto era de {} reais, e com o desconto, o valor ficou {} reais.".format(preço, preçoNovo))
# print(f"O valor antes do desconto era de {preço} reais e com o desconto ficou {preçoNovo} reais.")
# print("O valor sem desconto era de %d, e com o desconto ficou por %d" %(preço,preçoNovo))
# print("O valor do item com desconto foi de: %.6f." %preçoNovo)

# print(num,"é um número, enquanto",string,"é uma string!")
# print("{0} é um número, enquanto {1} é uma string!".format(num,string))
# print("%d é um número, enquanto %s é uma string!" %(num,string))
# print("Número com vírgula: %.2f!" %num)


import tensorflow as tf
import numpy as np
from bench.core.executer import Executer

def accuracy(pred, target, topk=1, thresh=None):
    if isinstance(topk, int):
        topk = (topk, )
        return_single = True
    else:
        return_single = False

    maxk = max(topk)
    if pred.shape[0] == 0:
        accu = [tf.zeros(tf.shape(pred)) for i in range(len(topk))]
        return accu[0] if return_single else accu
    pred_value, pred_label = tf.math.top_k(pred, maxk)
    pred_label = tf.transpose(pred_label)  # transpose to shape (maxk, N)
    correct = tf.equal(tf.cast(tf.reshape(target, (1, -1)), tf.int32), pred_label)
    if thresh is not None:
        # Only prediction values larger than thresh are counted as correct
        correct = tf.bitwise.bitwise_and(correct, tf.transpose(tf.math.greater(pred_value, thresh)))
    res = []
    for k in topk:
        correct_k = tf.reduce_sum(tf.cast(tf.reshape(correct[:k], [-1]), tf.float32), axis=0, keepdims=True)
        res.append(tf.multiply(correct_k, 100.0 / pred.shape[0]))
    return res[0] if return_single else res

def args_adaptor(np_args):
    output = tf.convert_to_tensor(np_args[0], tf.float32)
    target = tf.convert_to_tensor(np_args[1], tf.float32)

    return [output, target, 1]

def executer_creator():
    return Executer(accuracy, args_adaptor)


#Simo Andreas Novikov
#Ülesanne 03
#15.03.2022

from tkinter import *

aken = Tk()
aken.title('Ülesanne 3')
aken.configure(background='black')
aken.geometry('300x150')

Label(aken, text = 'Simo Andreas Novikov \n IT-21 \n 2022', fg="red", background="black", font="Tahoma 16 bold italic").pack(side = TOP, pady = 30)

aken.resizable(0, 0)

mainloop()


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

"""
@Author: xiezizhe
@Date: 23/6/2020 下午7:29
"""

from typing import List

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if not matrix:
            return 0

        m, n = len(matrix), len(matrix[0])

        ret = 0
        dp = [[0 for __ in range(n)] for _ in range(m)]

        # dp[:][0] = map(int, matrix[:][0])
        # dp[0][:] = map(int, matrix[0][:])

        for i in range(m):
            if matrix[i][0] == '1':
                dp[i][0] = 1
                ret = 1

        for i in range(n):
            if matrix[0][i] == '1':
                dp[0][i] = 1
                ret = 1

        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == '1':
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
                    ret = max(ret, dp[i][j])

        return ret * ret

if __name__ == "__main__":
    s = Solution()
    print(s.maximalSquare([["0", "1"], ["1", "0"]]))