"""
Inputs:
    - data: Source data in the form of dataframe
    - axis: X-axis variable
    - legend: Secondary variable
    - number_of_class: Number of class user wants to specify
    - sql_filter: SQL queries for filter
    - plot_type: Frequency plot type ("Bar Chart","Line Chart","Histogram")
Output:
    - Data in the form of dataframe with summary table and plot
"""
import traceback
import pandas as pd
from dft import df_plot
from dft.base_execution_handler import BaseExecutionHandler

class ExecutionHandler(BaseExecutionHandler):
    def execute(self, data: pd.DataFrame, axis, legend, sql_filter, number_of_class=5):

        def data_filter(df: pd.DataFrame, sql):
            try:
                df = df.query(f'{sql}')
            except Exception as e:
                print("Malformed SQL. Filtering aborted")
                print(e)
            return df

        def value_to_interval(x, classes, interval_column):
            for i in range(classes):
                if x in interval_column[i]:
                    return interval_column[i]
                else:
                    pass
            return y

        try:
            data = data_filter(data, sql_filter)
            table = pd.DataFrame(data[axis].value_counts(bins=number_of_class, sort=False)).reset_index()
            data[axis] = data[axis].apply(value_to_interval, args=(number_of_class, table['index']))
            data[axis] = data[axis].astype(str)
            table = pd.pivot_table(data, index=axis, values=data.columns[0],
                                   columns=[legend], aggfunc='count').fillna(0).reset_index()
            table[table.columns[0]] = table[table.columns[0]].astype(str)
            df_plot.clubbed_histogram('Frequency Distribution' + ' Of ' + axis + ' For different' + legend,
                                      table.columns[0], list(table.columns[1:]), table)

        except Exception as e:
            print(e)
            print(traceback.format_exc())
            raise
        return table


'''
@Date    : 2022-06-22
@Author  : Maksim Soloviov

Practical task 3 for lesson 4
3. Для чисел в пределах от 20 до 240 найти числа, кратные 20 или 21.
Решите задание в одну строку.
Подсказка: используйте функцию range() и генератор.
'''

def main():
    ''' Main body '''
    # Пусть до 240 включительно
    result_list = [i for i in range(20, 241) if i % 20 == 0 or i % 21 == 0]
    print(result_list)

if __name__ == '__main__':
    main()


from typing import List

from rxbp.indexed.observables.concatindexedobservable import ConcatIndexedObservable
from rxbp.indexed.selectors.bases.concatbase import ConcatBase
from rxbp.indexed.selectors.flowablebaseandselectors import FlowableBaseAndSelectors
from rxbp.mixins.flowablemixin import FlowableMixin
from rxbp.subscriber import Subscriber
from rxbp.subscription import Subscription

class ConcatIndexedFlowable(FlowableMixin):
    def __init__(self, sources: List[FlowableMixin]):
        super().__init__()

        self._sources = sources

    def unsafe_subscribe(self, subscriber: Subscriber) -> Subscription:
        def gen_subscriptions():
            for source in self._sources:
                subscription = source.unsafe_subscribe(subscriber)
                yield subscription

        subscriptions = list(gen_subscriptions())

        observable = ConcatIndexedObservable(
            sources=[s.observable for s in subscriptions],
            scheduler=subscriber.scheduler,
            subscribe_scheduler=subscriber.subscribe_scheduler,
        )

        base = ConcatBase(
            underlying=tuple(s.index for s in subscriptions),
            sources=tuple(observable.selectors),
        )

        return subscriptions[0].copy(
            index=FlowableBaseAndSelectors(base=base),
            observable=observable,
        )


from TreeNode import TreeNode

class BalancedBinaryTree:
    def isBalanced(self, root: TreeNode) -> bool:
        if not root:
            return True
        return abs(self.height(root.left)-self.height(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)

    def height(self, node):
        if not node:
            return 0
        return 1+max(self.height(node.left), self.height(node.right))

if __name__ == '__main__':
    init = BalancedBinaryTree()
    root = TreeNode(7)
    root.left = TreeNode(3)
    root.right = TreeNode(15)
    root.right.left = TreeNode(9)
    root.right.right = TreeNode(20)

    print(init.isBalanced(root))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 30 09:59:03 2021

@author: andy
"""
import json
import os
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.style
#import matplotlib.image as mpimg
#from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import seaborn as sns
import configparser
import re
import math

class Evaluation:

    list_results=[]     #List results
    Data=pd.DataFrame() #To store all results in one DataFrame
    plot_confi={}

    def readConfig(self):
        print('Including values from configuration file\n')
        self.config = configparser.ConfigParser()
        self.config.optionxform=str
        self.file='profileconfig.ini'
        self.config.read(self.file)
        self.sections=self.config.sections()
        for i in range(len(self.sections)):
            Ev.plot_confi[self.sections[i]] = dict(self.config.items(self.sections[i]))
        print('Configuration completed\n')

    def load_df(self,path):
        df_dict={}

        os.chdir(path)
        listfolders = os.listdir()

        for datafolder in listfolders:
            os.chdir(path+'/'+datafolder)   #Jump in datafolder
            df_dict[datafolder]=pd.DataFrame()
            Data=pd.DataFrame()
            list_results =[]
            i=0
            while i in range(len(os.listdir())):
                for files in os.listdir():
                    file=open(files,'r')            #open json file
                    file_load=json.load(file)       #load json file
                    list_results.append(file_load[0])  #fill list with results of the loaded json file
                    #Data.append(list_results[i],ignore_index=True)
                    if i==0:
                        Data=pd.DataFrame.from_dict(list_results[0],orient='index')
                    Data[i]=pd.DataFrame.from_dict(list_results[i],orient='index')

                    i+=1
                df_dict[datafolder] = Data.T

        return df_dict

    def loadfiles(self,directory):

        #Loads json files and returns a Dataframe
        #You can take a look into the shape of the returned df with the commnd df.info
        os.chdir(directory)

        self.listfiles=os.listdir() #Get a list of all files stored in target directory

        '''Load files in DataFrame'''
        for i in range(len(self.listfiles)):

             self.file=open(self.listfiles[i],'r')        #Open file
             self.file_load=json.load(self.file)          #Load from file
             Ev.list_results.append(self.file_load[0])    #Take the Data of the file that is stored in first list entry
             if i==0:                           #
                 Ev.Data=pd.DataFrame.from_dict(Ev.list_results[0],orient='index')    #initialize DataFrame
             Ev.Data[i]=pd.DataFrame.from_dict(Ev.list_results[i],orient='index')     #Add columns from list_results to df
        Data2=Ev.Data.T
        return Data2

    def convertunits(self, dataframetoconvert):
        #Change the values and units from the values that are set to "on" in the config file
        #Return the a new dataframe and a list with elements to be plotted
        self.list_to_be_print=[] #list with elements to be plotted

        print('Change datatype of:\n')
        for item in Ev.plot_confi['plots']:

            if Ev.plot_confi['plots'][item] == 'on': #item = column name as a str

                self.list_to_be_print.append(item)
                print(item)

                for val in range(len(dataframetoconvert[item])):
                    temp_string=dataframetoconvert.loc[val,item]
                    if type(dataframetoconvert.loc[val,item]) !='float':
                        #dataframetoconvert.loc[val,item]=int(temp_string[:temp_string.rfind('.')])
                        dataframetoconvert.loc[val,item]=float(re.findall(r'[\d.]+',temp_string)[0])
                    else:
                        dataframetoconvert.loc[val,item]=(re.findall(r'[\d.]+',temp_string)[0])

        dataframetoconvert['NumThreadsPerBlock*NumBlocksPerGrid']=dataframetoconvert['NumThreadsPerBlock']*dataframetoconvert['NumBlocksPerGrid']
        dataframetoconvert['NumThreadsPerBlock*NumBlocksPerGrid']=dataframetoconvert['NumThreadsPerBlock*NumBlocksPerGrid'].astype('int')
        return dataframetoconvert,self.list_to_be_print

    def convertunits_2(self):

        dataframes_threated={}

        for df in dataframes:
            # reduce dataframes
            # iter_1024 = dataframes['iteration_fix_1024'][['NumIterations','NumThreadsPerBlock', 'NumBlocksPerGrid','EvtsPerSec[MatrixElems] (3)']]
            temp_df =pd.DataFrame()
            temp_df = dataframes[df][['NumIterations','NumThreadsPerBlock', 'NumBlocksPerGrid',
                                      'EvtsPerSec[MatrixElems] (3)','EvtsPerSec[Rnd+Rmb+ME](123)',
                                      'EvtsPerSec[Rmb+ME] (23)']]

            columns_to_convert = ['EvtsPerSec[MatrixElems] (3)','EvtsPerSec[Rnd+Rmb+ME](123)',
                                      'EvtsPerSec[Rmb+ME] (23)']
            for column in columns_to_convert:

                for val in range(len(temp_df[column])):
                    temp_string=temp_df.loc[val,column]

                    temp_df.loc[val,column]=int(float(re.findall(r'[\d.]+',temp_string)[0]))
            temp_df['gridsize']=temp_df['NumThreadsPerBlock']*temp_df['NumBlocksPerGrid']
            temp_df['gridsize']=temp_df['gridsize'].astype(int)
            dataframes_threated[df]=temp_df

        return dataframes_threated

    def plots(self,df,plotlist):
        plt.cla()
        plt.clf()

        for yaxis in plotlist:

            fig = plt.figure()
            ax = plt.subplot()

            #set figure size
            fig.set_size_inches(18,10)

            #remove frame
            ax.spines['right'].set_visible(False)
            ax.spines['top'].set_visible(False)

            #enable grid
            plt.rcParams['grid.linestyle']=':'
            ax.yaxis.grid()

            #setup x-axis
            ax.set_xscale('log')
            plt.xticks(df['gridsize'])
            ax.set_xticklabels(df['gridsize'],rotation=75,fontsize=13.5)

            #setup y-axis
            #logarithmic
            plt.ylim((min(df[yaxis])-min(df[yaxis])*0.30),max(df[yaxis])*3)
            ax.set_yscale('log')
            plt.yticks(size=13.5)
            #linear scale
            #plt.ylim(0,max(df[yaxis])*1.3)

            #Labels and titel
            plt.xlabel('Gridsize',fontsize=15)
            plt.ylabel('Troughput\n'+yaxis,fontsize=13.5)
            plt.title(yaxis,fontsize=15)

            # plt.ylabel(yaxis,fontsize=30)
            # plt.xlabel('NumThreadsPerBlock*NumBlocksPerGrid',fontsize=30)
            # plt.rcParams['axes.facecolor']='whitesmoke'
            # plt.rcParams['ytick.labelsize']=25
            # #ax.set_yscale('log')
            # ax.set_facecolor('darkgray')
            # ax.set_xscale('log')#(1)
            # ax.set_xticklabels(df['gridsize'],rotation=75)
            # ax.set_facecolor('silver')
            # #print(type(yaxis))

            for k in sorted(df['NumThreadsPerBlock'].unique(),reverse=True):

                    d=df.loc[df['NumThreadsPerBlock']==k]
                    ax.scatter(
                        d['gridsize'],
                        d[yaxis],
                        label=k,
                        s=k*2,
                        c=Ev.color(k),
                        alpha=Ev.al(k),
                        edgecolors='black'
                        )
                    ax.legend(loc='upper left',title='Threads Per Block',prop={'size':15})
                    plt.xticks(df['gridsize'])
                    #(1)
            #plt.rcParams['legend.title_fontsize']='large'
            #plt.text(16400, 250000, 'Here we have space for some\nfurther information like:\n\nCuda\nepoch2\ngg_ttgg',fontsize=25)
            plt.show()
            fig.savefig('/home/andy/cernbox/data/raw/data'+'epoch2_ee_mumu_gcheck_float'+yaxis)

    def data_compare(self,df_dict,compare_list,stat):
        #This function takes the dictinary of data frames and plots the selected df from the list
        #stat means the statistic value like "max", "min","avg"

        df_to_be_plotted=pd.DataFrame()
        gridsizelist=sorted(dataframes_conv[list(dataframes_conv.keys())[0]]['gridsize'].astype(int).unique())

        #DataFrame treatment:

        for gs in gridsizelist: #get the gridsize values
            for df in compare_list:
                #self.temp_df=test_i=test[(test['gridsize']==1024)]
                temp_df=df_dict[df][(df_dict[df]['gridsize']==gs)]
                temp_df['process']=df
                if temp_df.empty:
                    pass
                else:
                    df_to_be_plotted=df_to_be_plotted.append(temp_df[(temp_df['EvtsPerSec[MatrixElems] (3)']
                                                               ==eval(stat)(temp_df['EvtsPerSec[MatrixElems] (3)']))])
                    df_to_be_plotted=df_to_be_plotted.astype({'gridsize':int})

        fig,ax = plt.subplots()

        ax.set_xscale('log')
        plt.ylim((0,1e9))
        plt.xticks(df_to_be_plotted['gridsize'])
        plt.suptitle('space for a smart title')
        plt.rcParams['ytick.labelsize']=10
        max_tp=max(df_to_be_plotted['EvtsPerSec[MatrixElems] (3)'])
        max_tp=round(max_tp/(1e9),3)
        plt.text(64, 200000000,'max Throughput\n'+str(max_tp)+'E9 s-1')
        #plt.text(32, 900000000, 'max throughput from profiler: %i s^-1'%epoch2_ee_mumu_double)
        #ax.legend(loc='upper left',title='yolo')

        sns.scatterplot(data=df_to_be_plotted,x='gridsize',y='EvtsPerSec[MatrixElems] (3)',
                        hue='process',legend='full',style='process',palette='deep')
        ax.set_xticklabels(df_to_be_plotted['gridsize'],rotation=75)

        return df_to_be_plotted

    def data_compare2(self,df_dict,compare_list):
        #Takes a dictionary with dataframes and plots it in the same scatter plot

        fig = plt.figure()
        ax1 = plt.subplot()

        fig.set_size_inches(12.5,5.5)

        #remove frame
        ax1.spines['right'].set_visible(False)
        ax1.spines['top'].set_visible(False)

        #enable grid
        plt.rcParams['grid.linestyle']=':'
        plt.grid()

        #setup x axis
        ax1.set_xscale('log')
        plt.xticks(df_dict[list(df_dict.keys())[0]]['gridsize'])
        ax1.set_xticklabels(df_dict[list(df_dict.keys())[0]]['gridsize'],rotation=75)

        #setup y axis
        #get maximum value of all df for ylim
        max_y = [max(df_dict[df]['EvtsPerSec[MatrixElems] (3)']) for df in df_dict]
        #plt.ylim(-0.1*10**9,max(max_y)*1.3)
        plt.ylim(10**5,max(max_y)*10)
        ax1.set_yscale('log')

        #Add labels and title
        plt.ylabel('Throughput\nMatrix Elements [s-1]')
        plt.xlabel('Gridsize')
        plt.title('Cuda throughput for ee_mumu on NVIDIA T4\n')

        #Change colormap. More info here https://matplotlib.org/stable/tutorials/colors/colormaps.html
        cmap=plt.get_cmap('Set1')

        i=1
        for data in compare_list:
            #Get maximum values for each dataset
            maxima_y=max(df_dict[data]['EvtsPerSec[MatrixElems] (3)'])
            maxima_x=df_dict[data].loc[df_dict[data]['EvtsPerSec[MatrixElems] (3)']==maxima_y,'gridsize'].item()

            #label maximum values
            length=len(str(maxima_y))-1
            label_maximas=str(round(maxima_y*10**-(length),3))+'e'+str(length)

            #plot datasets
            ax1.scatter(df_dict[data]['gridsize'].to_list(),df_dict[data]['EvtsPerSec[MatrixElems] (3)'].to_list(),
                        label=data+ ' (max = %s)'%label_maximas,
                        color=cmap(i),
                        s=150,alpha=0.9)
            #Get next cmap color
            i+=1

            #plot max values
            ax1.scatter(maxima_x,maxima_y,c='r',marker='o',s=50)

        ax1.legend(loc='upper left')

        plt.show()

    def dataframes_statistical_transfomation(self,df_dict,stat):
        #This functions takes a dictionary of dataframes and returns a dictionary with dataframes
        #where the dataframes contain only the gridsize values according to the statistical expression
        #which was given to the function like max, min, etc..
        df_dict_to_return={}

        #Get a list of gridsize
        gridsize = sorted(df_dict[list(df_dict.keys())[0]]['gridsize'].astype(int).unique())
        for df in df_dict:
            df_dict_to_return[df]=pd.DataFrame()
            for gs in gridsize:
                temp_df=df_dict[df][(df_dict[df]['gridsize']==gs)]

                if temp_df.empty:
                    pass
                else:
                    df_dict_to_return[df]=df_dict_to_return[df].append(temp_df[(temp_df['EvtsPerSec[MatrixElems] (3)']
                                                                      ==eval(stat)(temp_df['EvtsPerSec[MatrixElems] (3)']))])
                    df_dict_to_return[df]=df_dict_to_return[df].astype({'gridsize':int})
        return df_dict_to_return

    def al(self,value):
        if value == 32:
            self.alpha = .5
        elif value == 64:
            self.alpha = 0.75
        elif value == 128:
            self.alpha = 0.75
        elif value == 256:
            self.alpha=1
        return self.alpha

    def color(self,value):
        if value == 32:
            self.col = 'midnightblue'
        elif value == 64:
            self.col = 'sienna'
        elif value == 128:
            self.col = 'aqua'
        elif value == 256:
            self.col='lightcyan'
        return self.col

if __name__=='__main__':

    Ev = Evaluation()
    Ev.readConfig()
    #logo=mpimg.imread('/home/andy/cernbox/Madgraph/profiler/Logo/Logo_CERN.png')
    #imagebox=OffsetImage(logo)
    path='/home/andy/cernbox/data/Andrea'
    dataframes=Ev.load_df(path) #returns a directory that contains df for all data given in the path
    plotlist= [item for item in Ev.plot_confi['plots']if Ev.plot_confi['plots'][item] == 'on']

    dataframes_conv=Ev.convertunits_2() #returns a df directory with converted units
    dataframes_statisical=Ev.dataframes_statistical_transfomation(dataframes_conv,'max')

    '''
    Ev.plots(dataframes_conv['gcheck.exe_epoch1_cuda_ee_mumu_double'],plotlist)
    '''
    #max(df_adj_units['EvtsPerSec[MatrixElems] (3)'])
    # To be done
    list_to_compare=['gcheck.exe_epoch1_cuda_ee_mumu_float','gcheck.exe_epoch1_cuda_ee_mumu_double']
    #test_df=Ev.data_compare(dataframes_conv,list_to_compare,'max')

    Ev.data_compare2(dataframes_statisical,list_to_compare)

    dataframes_statisical[list(dataframes_statisical.keys())[0]]
    dataframes_statisical[list(dataframes_statisical.keys())[0]]['gridsize']
    dataframes_statisical['gcheck.exe_epoch1_cuda_ee_mumu_float'].dtypes


#! /usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
x = np.arange(0, 5, 0.1);
y = np.sin(x)
z = np.cos(x)
ax1.plot(x, y, x, z)
plt.show()


import jax
import sys

from experiments.parse_args import parse_args
from experiments.logging import init_logger, log_results
from util import *
from agents.agents import get_agent
from environments.rollout import RolloutWrapper

def make_train(args):
    def train(rng):
        # --- Initialize environment ---
        env = RolloutWrapper(args.env_name, args.num_rollout_steps)
        env_params = env.default_env_params
        rng, _rng = jax.random.split(rng)
        _rng = jax.random.split(_rng, args.num_env_workers)
        obsv, env_state = env.batch_reset(_rng, env_params)

        # --- Initialize agent train states and step function ---
        rng, _rng = jax.random.split(rng)
        # train_state contains actor (and critic if used) to be used for rollouts,
        # aux_train_states contains all other trainable parameters
        train_state, aux_train_states, agent_train_step_fn = get_agent(
            args,
            _rng,
            env.obs_shape,
            env.num_actions,
            env.discrete_actions,
            env.action_lims,
        )

        # --- Execute train loop ---
        def _train_step(runner_state, _):
            train_state, aux_train_states, env_state, last_obs, rng = runner_state
            # --- Collect trajectories ---
            rng, _rng = jax.random.split(rng)
            _rng = jax.random.split(_rng, args.num_env_workers)
            new_env_state, new_last_obs, traj_batch = env.batch_rollout(
                _rng, train_state, env_params, last_obs, env_state
            )

            # --- Update agent ---
            rng, _rng = jax.random.split(rng)
            train_state, aux_train_states, loss, metric = agent_train_step_fn(
                train_state, aux_train_states, traj_batch, new_last_obs, _rng
            )

            runner_state = (
                train_state,
                aux_train_states,
                new_env_state,
                new_last_obs,
                rng,
            )
            return runner_state, (loss, metric, traj_batch)

        rng, _rng = jax.random.split(rng)
        runner_state = (train_state, aux_train_states, env_state, obsv, _rng)
        runner_state, (loss, metric, traj_batch) = jax.lax.scan(
            _train_step, runner_state, None, args.num_train_steps
        )
        ret = {
            "runner_state": runner_state,
            "metrics": metric,
            "loss": loss,
        }
        return ret

    return train

def train_agents(args):
    # --- Initialize experiment ---
    init_logger(args)
    train_fn = make_train(args)

    # --- Run training for num_agents ---
    rng = jax.random.PRNGKey(args.seed)
    rng = jax.random.split(rng, args.num_agents)
    results = jax.jit(jax.vmap(train_fn))(rng)
    log_results(args, results)

def main(cmd_args=sys.argv[1:]):
    args = parse_args(cmd_args)
    experiment_fn = jax_debug_wrapper(args, train_agents)
    return experiment_fn(args)

if __name__ == "__main__":
    main()


from typing import List, Optional

import numpy as np

import pyrado
from pyrado.environments.base import Env
from pyrado.logger.step import LoggerAware
from pyrado.policies.base import Policy
from pyrado.sampling.sampler import SamplerBase
from pyrado.sampling.step_sequence import StepSequence

def select_cvar(rollouts, epsilon: float, gamma: float = 1.0):
    """
    Select a subset of rollouts so that their mean discounted return is the CVaR(eps) of the full rollout set.

    :param rollouts: list of rollouts
    :param epsilon: chosen return quantile
    :param gamma: discount factor to compute the discounted return, default is 1 (no discount)
    :return: list of selected rollouts
    """
    # Select epsilon-quantile of returns
    # Do this first since it is easier here, even though we have to compute the returns again
    # To do so, we first sort the paths by their returns
    rollouts.sort(key=lambda ro: ro.discounted_return(gamma))

    # Compute the quantile on a sorted list is easy
    num_sel_ros = round(len(rollouts) * epsilon)

    if num_sel_ros == 0:
        raise pyrado.ValueErr(given=num_sel_ros, g_constraint=0)

    # Only use the selected rollouts
    return rollouts[0:num_sel_ros]

class CVaRSampler(SamplerBase, LoggerAware):
    """
    Samples rollouts to optimize the CVaR of the discounted return.
    This is done by sampling more rollouts, and then only using the epsilon-qunatile of them.
    """

    def __init__(
        self, wrapped_sampler, epsilon: float, gamma: float = 1.0, *, min_rollouts: int = None, min_steps: int = None
    ):
        """
        Constructor

        :param wrapped_sampler: the inner sampler used to sample the full data set
        :param epsilon: quantile of rollouts that will be kept
        :param gamma: discount factor to compute the discounted return, default is 1 (no discount)
        :param min_rollouts: minimum number of complete rollouts to sample
        :param min_steps: minimum total number of steps to sample
        """
        self._wrapped_sampler = wrapped_sampler
        self.epsilon = epsilon
        self.gamma = gamma

        # Call SamplerBase constructor
        super().__init__(min_rollouts=min_rollouts, min_steps=min_steps)

    def set_min_count(self, min_rollouts=None, min_steps=None):
        # Set inner sampler's parameter values (back) to the user-specified number of rollouts / steps
        super().set_min_count(min_rollouts=min_rollouts, min_steps=min_steps)

        # Increase the number of rollouts / steps that will be sampled since we will discard (1 - eps) quantile
        # This modifies the inner samplers parameter values, that's ok since we don't use them afterwards
        if min_rollouts is not None:
            # Expand rollout count to full set
            min_rollouts = int(min_rollouts / self.epsilon)
        if min_steps is not None:
            # Simply increasing the number of steps as done for the rollouts is not identical, however it is goo enough
            min_steps = int(min_steps / self.epsilon)
        self._wrapped_sampler.set_min_count(min_rollouts=min_rollouts, min_steps=min_steps)

    def reinit(self, env: Optional[Env] = None, policy: Optional[Policy] = None):
        # Delegate to inner sampler
        self._wrapped_sampler.reinit(env=env, policy=policy)

    def sample(self) -> List[StepSequence]:
        # Sample full data set
        fullset = self._wrapped_sampler.sample()

        # Log return-based metrics using the full data set
        rets = np.asarray([ro.undiscounted_return() for ro in fullset])
        ret_avg = np.mean(rets)
        ret_med = np.median(rets)
        ret_std = np.std(rets)
        self.logger.add_value("full avg rollout len", np.mean([ro.length for ro in fullset]))
        self.logger.add_value("full avg return", ret_avg)
        self.logger.add_value("full median return", ret_med)
        self.logger.add_value("full std return", ret_std)

        # Return subset
        return select_cvar(fullset, self.epsilon, self.gamma)


""" Given a string, the task is to remove duplicates from it.
Expected time complexity O(n) where n is length of input string and extra space O(1) under the
assumption that there are total 256 possible characters in a string.

Note: that original order of characters must be kept same.

Input:
First line of the input is the number of test cases T. And first line of test case contains a string.

Output:
Modified string without duplicates and same order of characters.

Constraints:
1 <= T <= 15
1 <= |string|<= 1000

Example:
Input:
2
geeksforgeeks
geeks for geeks

Output:
geksfor
geks for """

# T = int(input())

S = input()
S_new = ""
N = len(S)

for i in range(0,N):
    if S.count(S[i])>1 and S_new.count(S[i]) > 0 :
        continue
    else:
        S_new +=S[i]

print(S_new)


# -*- coding: utf-8 -*-
# @Author: Krystian Spandel
# @Date:   2019-02-25 00:29:58
# @Last Modified by:   Krystian Spandel
# @Last Modified time: 2019-03-01 23:12:52

mimeTypes = {
    "application/octet-stream": "xxx",
    "application/x-gzip": "zip",
    "video/webm": "webm",
    "image/png": "png",
    "image/webp": "webp",
    "image/jpeg": "jpg",
    "image/gif": "gif",
    "audio/mpeg": "mp3",
    "video/mp4": "mp4",
    "application/x-dosexec": "exe",
    "text/html": "html",
    "text/plain": "txt",
    "image/x-icon": "ico",
    "image/svg": "svg",
}


from configurations import *

class Controller():
    '''
    Constructor to make a controller
    '''
    def __init__(self, gui, colour, x, y, width, height, text=''):
        self.gui = gui
        self.colour = colour
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def make_controller(self, outline = None):
        '''
        Function that makes a controller with a certain color of outline along with its true color
        Also creates the text and places it in the middle of the button
        '''
        if outline:
            pygame.draw.rect(self.gui.DISP, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0) #Create outline
            pygame.draw.rect(self.gui.DISP, self.colour, (self.x, self.y, self.width, self.height), 0) #Create actual box

        #If text is not empty
        if self.text != '':
            font = pygame.font.SysFont(FONT_name, 28)
            text = font.render(self.text, 1, BLACK)
            #Places the text in the middle with this formula
            self.gui.DISP.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

    def isHovering(self, position):
        '''
        Function that identifies if the position is considered to be a part of the controller
        :param position: position of the mouse
        :return: A boolean deciding if the position is valid
        '''
        # Pos is the mouse position or a tuple of (x,y) coordinates
        if position[0] > self.x and position[0] < self.x + self.width:
            if position[1] > self.y and position[1] < self.y + self.height:
                return True
        return False


import pyparsing
import unittest

from hcsvlab_robochef.annotations.annotation_parsers import *
from hcsvlab_robochef.annotations import *
from hcsvlab_robochef.art.ingest import ARTIngest
from hcsvlab_robochef.art.parser import *
from hcsvlab_robochef.art.sample import *
from hcsvlab_robochef.art.iterator import *

def unittests():
    res = unittest.TestSuite()
    res.addTest(unittest.makeSuite(ParsingTests))
    res.addTest(unittest.makeSuite(MetaTests))
    res.addTest(unittest.makeSuite(IngestTests))
    return res

class ParsingTests(unittest.TestCase):

    def test_simple_pause(self):

        rawText = "<,>"

        parser = pyparsing.OneOrMore( artpauseParser() )
        res = parser.parseString(rawText)

        self.assertEqual("[@( ,[pause:  0 -> 0])]", str(res))

    def test_simple_pause(self):

        rawText = "One of the jewels in the open garden scheme crown is opening today and this is just a garden to envy how would you like <,> to have <,> a beautiful sandstone cottage nestled underneath a waterfall with a little pond and then a creek that runs through with thousands of water dragons so tame they come up and just <,> kiss you. Would you like to live there"

        ingest = ARTIngest()
        res = ingest.extractAnnotations(rawText)

        self.assertEqual("[pause:  120 -> 120, pause:  130 -> 130, pause:  309 -> 309]", str(res[1]))

    def test_simple_correction(self):

        rawText = "{propagation} Mr Propergation"

        parser = pyparsing.OneOrMore( correctionParser() )
        res = parser.parseString(rawText)

        self.assertEqual("[@(,[correction: propagation 0 -> 0])]", str(res))

    def test_simple_interjection(self):

        rawText = "<E1 sounds reasonable> for his ability to open cosposting toilets so he can tell you"
        ingest = ARTIngest()
        parser = pyparsing.OneOrMore( interjectionParser() )
        res = parser.parseString(rawText)

        self.assertEqual("[@(,[interjection: E1 sounds reasonable 0 -> 0])]", str(res))

    def test_complex_interjection(self):

        rawText = "He's also known <E1 sounds reasonable> for his ability to open cosposting"
        ingest = ARTIngest()
        res = ingest.extractAnnotations(rawText)

        self.assertEqual("He's also known  for his ability to open cosposting", str(res[0]))
        self.assertEqual("[interjection: E1 sounds reasonable 16 -> 16]", str(res[1]))

    def test_extract_annotations(self):

        rawText = "Thanks for that John Hall now John Hall will be listening for the next hour 'cos Angus Stewart is here to take your calls eight-triple-three-one-thousand one-eight-hundred-eight-hundred-seven-oh-two something in the garden that's causing you problems give us a call right now and Angus can I mean y'know he is known in the trade as Mr popergation {propagation} Mr propagation. He's also known for his passion for natives and his love of o orchids am I right so far."
        ingest = ARTIngest()
        res = ingest.extractAnnotations(rawText)

        self.assertEqual("[correction: propagation 347 -> 347]", str(res[1]))

class IngestTests(unittest.TestCase):

    ingest = ARTIngest()

    def setUp(self):
        self.ingest.setMetaData('../input/ART/ART-corpus-catalogue.xls')

    #@unittest.skip("Tmp")
    def test_simple_speaker_turn_parsing(self):
        parsed_content = parseCompleteDocument("[P1] Well hello there.")
        self.assertEqual(2, len(parsed_content))
        self.assertEqual('P1', parsed_content[0][0])

        parsed_content  = parseCompleteDocument("[E1] Just some normal text\n and more text. [P2] and some more text.")
        self.assertEqual(4, len(parsed_content))
        self.assertEqual("E1", parsed_content[0][0])

    #@unittest.skip("Tmp")
    def test_parse_sample1(self):
        file = open("../systemtests/art/sample1.txt", "r")
        content = file.read()
        parsed_content = parseCompleteDocument(content)

        self.assertEqual(10, len(parsed_content))
        self.assertEqual("E1", parsed_content[6][0])

        for sample in ArtIterator(parsed_content):
            self.assertEqual((0, 10), sample)

    #@unittest.skip("Tmp")
    def test_parse_sample2(self):
        file = open("../systemtests/art/sample2.txt", "r")
        content = file.read()
        parsed_content = parseCompleteDocument(content)

        self.assertEqual("P1", parsed_content[8][0])

        index = 0
        for sample in ArtIterator(parsed_content):
            if (index == 0):
                # print parsed_content[204]
                self.assertEqual((0, 203), sample)
            else:
                self.assertEqual((204, 438), sample)
            index += 1

    #@unittest.skip("Tmp")
    def test_parse_sample3(self):
        file = open("../systemtests/art/sample3.txt", "r")
        content = file.read()
        parsed_content = parseCompleteDocument(content)

        self.assertEqual("Caller", parsed_content[12][0])

        index = 0
        for sample in ArtIterator(parsed_content):
            if (index == 0):
                # print parsed_content[262]
                self.assertEqual((0, 261), sample)
            else:
                self.assertEqual((262, 622), sample)
            index += 1

    #@unittest.skip("Tmp")
    def test_parse_sample4(self):
        file = open("../systemtests/art/sample4.txt", "r")
        content = file.read()
        parsed_content = parseCompleteDocument(content)

        self.assertEqual("E1", parsed_content[12][0])

        index = 0
        for sample in ArtIterator(parsed_content):
            if (index == 0):
                self.assertEqual((0, 405), sample)
            else:
                self.assertEqual((406, 1284), sample)
            index += 1

    def test_parse_sample6(self):
      file = open("../systemtests/art/sample6.txt", "r")
      content = file.read()
      parsed_content = parseCompleteDocument(content)

      for rawSample in ArtIterator(parsed_content):
        sample = Sample(parsed_content[rawSample[0]: rawSample[1]])
        self.assertEqual('John Laws', sample.getPrimarySpeaker())
        self.assertEqual('Mark', sample.getSecondarySpeaker())
        meta = self.ingest.findMetaData(sample)

    @unittest.skip("Test takes a while and has been commented out")
    def test_parse_original(self):
        file = open("../input/ART/Austgram-texts.txt", "r")
        content = file.read()
        parsed_content = parseCompleteDocument(content)

        for index in range(0, len(parsed_content) -1, 2):
            self.assertTrue(parsed_content[index][0][0] in ('P','C', 'E'))

    @unittest.skip("This test should not be executed, it is used instead of calling main when required")
    def test_ingest_samples(self):
        # self.ingest.ingestCorpus("../input/ART", "../output/ART")
        self.ingest.ingestCorpus("../systemtests/art", "../output/ART")

class MetaTests(unittest.TestCase):

    ingest = ARTIngest()

    def setUp(self):
        self.ingest.setMetaData('../input/ART/ART-corpus-catalogue.xls')

    def test_grouped_callers(self):
        come6 = self.ingest.file_meta['COME6']
        self.assertEqual('Jasmine', come6['table_person_13']['name'])
        self.assertEqual('F', come6['table_person_13']['gender'])

        self.assertEqual('Jimmy', come6['table_person_14']['name'])
        self.assertEqual('M', come6['table_person_14']['gender'])

    def test_find_meta_from_sample1(self):
        file = open("../systemtests/art/sample1.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            meta = self.ingest.findMetaData(sample)
            self.assertEqual('ABCE1', meta['sampleid'])

    def test_find_meta_from_sample2(self):
        file = open("../systemtests/art/sample2.txt", "rb")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            meta = self.ingest.findMetaData(sample)

            if index == 0:
                self.assertEqual('COMNE6', meta['sampleid'])
                index += 1
            else:
                self.assertEqual('COMNE7', meta['sampleid'])

    def test_find_meta_from_sample3(self):
        file = open("../systemtests/art/sample3.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            meta = self.ingest.findMetaData(sample)

            if index == 0:
                self.assertEqual('ABCE4', meta['sampleid'])
                index += 1
            else:
                self.assertEqual('ABCNE1', meta['sampleid'])

    def test_find_meta_from_sample4(self):
        file = open("../systemtests/art/sample4.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            meta = self.ingest.findMetaData(sample)

            if index == 0:
                self.assertEqual('NAT2', meta['sampleid'])
                index += 1
            else:
                self.assertEqual('NAT7', meta['sampleid'])

    def test_extract_of_raw_data(self):
        file = open("../systemtests/art/sample1.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            raw = sample.extractRawText()

    @unittest.skip("Commented out because test takes very long to execute")
    def test_extract_of_raw_data_for_original(self):
        file = open("../input/ART/Austgram-texts.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            raw = sample.extractRawText()

    def test_no_of_samples(self):
        self.assertEqual(29, len(self.ingest.file_meta))

    def test_extract_of_unknown_location(self):
        self.assertTrue(self.ingest.file_meta.has_key('NAT1'))
        self.assertEqual('', self.ingest.file_meta['NAT1']['location'])

    def test_extract_of_known_location(self):
        self.assertTrue(self.ingest.file_meta.has_key('ABCE1'))
        self.assertEqual('Sydney', self.ingest.file_meta['ABCE1']['location'])

    def test_extract_of_station(self):
        self.assertTrue(self.ingest.file_meta.has_key('COME3'))
        self.assertEqual('2GB', self.ingest.file_meta['COME3']['station'])

    def test_extract_of_program(self):
        self.assertTrue(self.ingest.file_meta.has_key('COME1'))
        self.assertEqual('The Garden Clinic', self.ingest.file_meta['COME1']['program'])

    def test_extract_of_recorded_date(self):
        self.assertTrue(self.ingest.file_meta.has_key('ABCE3'))
        self.assertEqual('2004/03/02', self.ingest.file_meta['ABCE3']['recorded'])

    def test_extract_of_proof_heard_and_final_check(self):
        self.assertTrue(self.ingest.file_meta.has_key('COME5'))
        self.assertEqual('y', self.ingest.file_meta['COME5']['proof_heard'])
        self.assertEqual('y', self.ingest.file_meta['COME5']['final_check'])

    def test_extract_of_known_subject(self):
        self.assertTrue(self.ingest.file_meta.has_key('COME6'))
        self.assertEqual(u'"installing stuff" "love song dedications" film reviews', self.ingest.file_meta['COME6']['subject'])

    def test_extract_of_unknown_subject(self):
        self.assertTrue(self.ingest.file_meta.has_key('COME7'))
        self.assertEqual('', self.ingest.file_meta['COME7']['subject'])

    def test_extract_of_known_ti(self):
        self.assertTrue(self.ingest.file_meta.has_key('NAT3'))
        self.assertEqual("Don't transcribe 0-7.05 (introduction, book reading and interview with child); 33.50-35.12 (book reading)", self.ingest.file_meta['NAT3']['transcriber_instructions'])

    def test_extract_of_known_transcribed(self):
        self.assertTrue(self.ingest.file_meta.has_key('NAT3'))
        self.assertEqual("2005/01/09", self.ingest.file_meta['NAT3']['transcribed'])

    def test_extract_nat4_caller_53_info(self):
        self.assertTrue(self.ingest.file_meta.has_key('NAT4'))

        # Check for person 1 who should be a presenter with the name Tony Delroy
        self.assertTrue(self.ingest.file_meta['NAT4'].has_key('table_person_1'))
        self.assertEqual('Tony Delroy', self.ingest.file_meta['NAT4']['table_person_1']['name'])
        self.assertEqual('presenter', self.ingest.file_meta['NAT4']['table_person_1']['role'])

        # Check for person 2 who should be a expert with the name Dr Barry Wren
        self.assertTrue(self.ingest.file_meta['NAT4'].has_key('table_person_2'))
        self.assertEqual('Barry Wren', self.ingest.file_meta['NAT4']['table_person_2']['name'])
        self.assertEqual('Gynecological Researcher/author', self.ingest.file_meta['NAT4']['table_person_2']['role'])

        # Check for person 3 who should be a caller with the name Carol
        self.assertTrue(self.ingest.file_meta['NAT4'].has_key('table_person_3'))
        self.assertEqual('Carol', self.ingest.file_meta['NAT4']['table_person_3']['name'])
        self.assertEqual('caller', self.ingest.file_meta['NAT4']['table_person_3']['role'])

        # Check for person 54 who should be a caller with the name Carol
        self.assertTrue(self.ingest.file_meta['NAT4'].has_key('table_person_54'))
        self.assertEqual('Ian', self.ingest.file_meta['NAT4']['table_person_54']['name'])
        self.assertEqual('caller', self.ingest.file_meta['NAT4']['table_person_54']['role'])
        self.assertEqual('M', self.ingest.file_meta['NAT4']['table_person_54']['gender'])

    def test_extract_normal_name(self):
        file = open("../systemtests/art/sample1.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            self.assertEqual('Simon Marnie', sample.constructSpeakerName(parsedContent[item[0]: item[1]][0]))

    def test_extract_short_name(self):
        file = open("../systemtests/art/sample5.txt", "r")
        content = file.read()
        parsedContent = parseCompleteDocument(content)

        index = 0
        for item in ArtIterator(parsedContent):
            sample = Sample(parsedContent[item[0]: item[1]])
            self.assertEqual('Les', sample.constructSpeakerName(parsedContent[item[0]: item[1]][0]))
            return


import time
import tkinter
from tkinter import *
from tkinter import ttk
from clase_sociedad_anonima import Sociedad_anonima

#{} []
#CREAR Ventana----------
ventana = Tk()
ventana.title = "Parcial 1"
ventana.geometry("1500x710")
#ventana.configure(bg='#49A')

tabla = ttk.Treeview(ventana, columns=("col1","col2","col3","col4","col5","col6","col7","col8","col9","col10"))

#instanciar la clase para asignar valores a los atributos y utilizar los métodos

lista=[]
clic = 0
def guardaDatos():
    registro=Sociedad_anonima()
    #registro= centro_educativo()

    #asignar los valores a los atributos
    registro.codigo = txt_codigo.get()
    registro.nombre = txt_nombre.get()
    registro.direccion = txt_direccion.get()
    registro.telefono = txt_telefono.get()
    #registro.director = txt_director.get()
    registro.director = "Carlos Ortiz"
    registro.url = "WWW.ACADEMIA.COM.GT"
    registro.hombres= txt_hombres.get()
    registro.mujeres= txt_mujeres.get()
    registro.sociedad= txt_sociedad.get()
    registro.representante= txt_representante.get()
    registro.correoR= txt_correoR.get()

    #agregando el estudiante a la lista
    lista.append(registro)
    generarTabla()
    limpiarCajasTexto()

    #limitar el numero de registros a 5
    global clic
    clic += 1
    if clic >= 6:
        print("BASE DE DATOS LLENA,se cerrara en 3 segundos")
        duracion = 5
        time.sleep(duracion)
        exit()

def generarTabla():
    for fila in tabla.get_children():
        tabla.delete(fila)

    #establecer el tamaño de las columnas
    tabla.column("#0", width=125)
    tabla.column("col1", width=125)
    tabla.column("col2", width=125)
    tabla.column("col3", width=125)
    tabla.column("col4", width=125)
    tabla.column("col5", width=125)
    tabla.column("col6", width=125)
    tabla.column("col7", width=125)
    tabla.column("col8", width=125)
    tabla.column("col9", width=125)
    tabla.column("col10", width=125)

    tabla.heading("#0", text="Codigo", anchor=CENTER)
    tabla.heading("col1", text="Nombre", anchor=CENTER)
    tabla.heading("col2", text="Direccion", anchor=CENTER)
    tabla.heading("col3", text="Telefono", anchor=CENTER)
    tabla.heading("col4", text="Director", anchor=CENTER)
    tabla.heading("col5", text="URL", anchor=CENTER)
    tabla.heading("col6", text="Cant.Hombres", anchor=CENTER)
    tabla.heading("col7", text="Cant.Mujeres", anchor=CENTER)
    tabla.heading("col8", text="Nombre Sociedad", anchor=CENTER)
    tabla.heading("col9", text="Nombre Representante", anchor=CENTER)
    tabla.heading("col9", text="Correo Representante", anchor=CENTER)

    #ciclo para pasar los elementos de lista
    for registro in lista:
        tabla.insert("",END, text=registro.codigo, values=(registro.nombre, registro.direccion, registro.telefono, registro.director, registro.url, registro.hombres, registro.mujeres, registro.sociedad, registro.representante, registro.correoR))
    tabla.pack(fill= tkinter.X)

def limpiarCajasTexto():
    #borrar el contenido de los controles Entry
    txt_codigo.delete(0,"end")
    txt_nombre.delete(0,"end")
    txt_direccion.delete(0,"end")
    txt_telefono.delete(0,"end")
    txt_hombres.delete(0,"end")
    txt_mujeres.delete(0,"end")
    #txt_director.delete(0,"end")
    #txt_url.delete(0,"end")
    txt_sociedad.delete(0,"end")
    txt_representante.delete(0,"end")
    txt_correoR.delete(0,"end")

    #pone el foco a este elemento
    txt_codigo.focus_set()

#fondo       letras
#bg="red", ,fg="blue"

#bloque de creacion cajas de texto en ventana - INGRESO DE DATOS
fuente = ("Arial", 14)

lbl_titulo = Label(ventana, text="PARCIAL No.1 - Carlos Ortiz\nUSAC-EFPEM", font=("Arial","14"),fg="RED")

lbl_codigo = Label(ventana, text="Codigo:", font = fuente,fg="blue")
txt_codigo = Entry(ventana, font= fuente)

lbl_nombre = Label(ventana, text="Nombre:", font = fuente,fg="blue")
txt_nombre = Entry(ventana, font= fuente)

lbl_direccion = Label(ventana, text="Direccion:", font = fuente,fg="blue")
txt_direccion = Entry(ventana, font= fuente)

lbl_telefono = Label(ventana, text="Telefono:", font = fuente,fg="blue")
txt_telefono = Entry(ventana, font= fuente)

#lbl_director = Label(ventana, text="Director:", font = fuente,fg="blue")
#txt_director = Entry(ventana, font= fuente)

#lbl_url = Label(ventana, text="Pagina URL:", font = fuente,fg="blue")
#txt_url = Entry(ventana, font= fuente)

lbl_hombres = Label(ventana, text="Cant.Hombres:", font = fuente,fg="blue")
txt_hombres = Entry(ventana, font= fuente)

lbl_mujeres = Label(ventana, text="Cant.Mujeres:", font = fuente,fg="blue")
txt_mujeres = Entry(ventana, font= fuente)

lbl_sociedad = Label(ventana, text="Sociedad Anonima:", font = fuente,fg="blue")
txt_sociedad = Entry(ventana, font= fuente)

lbl_representante = Label(ventana, text="Nombre Representante:", font = fuente,fg="blue")
txt_representante = Entry(ventana, font= fuente)

lbl_correoR = Label(ventana, text="Correo Representante:", font = fuente,fg="blue")
txt_correoR = Entry(ventana, font= fuente)

btn_guardar = tkinter.Button(ventana, text="Guardar  -solo 5 Registros-", command=guardaDatos, font=fuente, bg="#FFF", activebackground="yellow")

#asignar modulo a bloque de creacion fill de labely textos
lbl_titulo.pack()

lbl_codigo.pack(anchor = tkinter.W)
txt_codigo.pack(fill = tkinter.X)

lbl_nombre.pack(anchor = tkinter.W)
txt_nombre.pack(fill = tkinter.X)

lbl_direccion.pack(anchor = tkinter.W)
txt_direccion.pack(fill = tkinter.X)

lbl_telefono.pack(anchor = tkinter.W)
txt_telefono.pack(fill = tkinter.X)

#lbl_director.pack(anchor = tkinter.W)
#txt_director.pack(fill = tkinter.X)

#lbl_url.pack(anchor = tkinter.W)
#txt_url.pack(fill = tkinter.X)

lbl_hombres.pack(anchor = tkinter.W)
txt_hombres.pack(fill = tkinter.X)

lbl_mujeres.pack(anchor = tkinter.W)
txt_mujeres.pack(fill = tkinter.X)

lbl_sociedad.pack(anchor = tkinter.W)
txt_sociedad.pack(fill = tkinter.X)

lbl_representante.pack(anchor = tkinter.W)
txt_representante.pack(fill = tkinter.X)

lbl_correoR.pack(anchor = tkinter.W)
txt_correoR.pack(fill = tkinter.X)

#mandar a llamar a accion del boton
btn_guardar.pack(fill = tkinter.X)

#inicio de modulo ventana
ventana.mainloop()


from django.shortcuts import render
from .models import Course, UserCourses, CourseLesson
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth.decorators import login_required

# Create your views here.
def index(req):
    allcourses = Course.objects.all()
    usercourses = []
    if req.user.is_authenticated:
        usercourses = [i.course for i in UserCourses.objects.filter(user=req.user)]

    return render(req, 'courses.html',{
        'allcourses':allcourses,
        'usercourses':usercourses,
    })

@login_required
def usercourses(req):
    user_courses = UserCourses.objects.filter(user=req.user)
    if len(user_courses) == 0:
        print('No courses')
        user_courses=None
    return render(req, 'user_courses.html',{
        'user_courses':user_courses,
    })

@login_required
def addcourse(req):
    if req.method == 'GET':
        user = req.user
        course_to_add_name = req.GET.get('coursename')
        print(user_has_course(user,course_to_add_name))
        if user_has_course(user,course_to_add_name):
            return HttpResponse("Course not added"+' '+ course_to_add_name)
        elif user_has_course(user,course_to_add_name) == None:
            return HttpResponse('No such course named' + ' ' + course_to_add_name)
        else:
            course = Course.objects.get(course_name=course_to_add_name)
            usercourse = UserCourses(user=user, course=course)
            usercourse.save()
            return HttpResponseRedirect(reverse('user_courses'))

@login_required
def remove_course(req):
    if req.method == 'GET':
        user = req.user
        course_to_remove_name = req.GET.get('coursename')
        print(user_has_course(user,course_to_remove_name))
        if user_has_course(user,course_to_remove_name):
            course = Course.objects.get(course_name=course_to_remove_name)
            usercourse = UserCourses.objects.get(course=course, user=user)
            usercourse.delete()
            return HttpResponseRedirect(reverse('user_courses'))

        elif user_has_course(user,course_to_remove_name) == None:
            return HttpResponse('No such course named' + ' ' + course_to_remove_name)
        else:
            return HttpResponse("Course not removed"+' '+ course_to_remove_name)

def user_has_course(user,course_name):
    all_user_courses = [i.course for i in UserCourses.objects.filter(user=user)]
    try:
        course = Course.objects.get(course_name=course_name)
    except Course.DoesNotExist:
        course = None
    if course==None:
        return course
    elif course in all_user_courses:
        return True
    else:
        return False

def python_beginners_course(req):
    course = Course.objects.get(course_url='python-beginners-course')
    course_lessons = CourseLesson.objects.filter(course=course)
    print(course_lessons)
    return render(req, course.course_url+'/coursepage.html', {
        'course_lessons':course_lessons,
    })

def web_development_easy(req):
    return HttpResponse('Under development')

def lesson_urls(lesson):
    course = lesson.course
    def lesson_view(req):
        print(str(lesson.lesson_url))
        return render(req, lesson.course.course_url+'/'+lesson.lesson_url+'.html',{
            'lesson':lesson,
        })
    return lesson_view


import sys

INF = float('inf')

# input functions
def read_int():
    return int(sys.stdin.readline())

def read_ints():
    return list(map(int, sys.stdin.readline().split()))

# output functions
def print_yes_no(condition):
    print('YES' if condition else 'NO')

def print_array(arr, sep=' '):
    print(sep.join(map(str, arr)))

def solve():
    n = read_int()
    a = read_ints()

    min_unit = [[]]
    diff = INF

    for i in range(n-1):
        temp_diff = abs(a[i]-a[i+1])
        if temp_diff < diff:
            diff = temp_diff
            min_unit[0] = [i+1,i+2]

    # anticlock
    if abs(a[0] - a[-1]) < diff:
        min_unit[0] = [n, 1]

    print_array(min_unit[0])

if __name__ == '__main__':
    solve()


import logging

import torch
import torch.nn.functional as F
from transformers import AutoModelForMaskedLM

from nupic.research.frameworks.pytorch.model_utils import (
    filter_modules,
    set_module_attr,
)

class DistillationTrainerMixin:
    """
    Mixin to HF Trainer.
    Initialize required arguments for Knowledge Distillation.
    Replace compute_loss with modified function.
    Replaces label_smoother with KDLoss (will override regular label_smoother).

    To deactivate distillation, call trainer.deactivate_distillation() and will
    fall back to regular loss computation.
    """

    def __init__(self, *args, **kwargs):
        """
        Add following variables under 'trainer_mixin_args' through the training
        arguments.

        :param teacher_model_names_or_paths: List of pretrained model names or paths to
                                             use as teachers in knowledge distillation.
        :param teacher_models_cache_dir: (optional) directory to load and save
                                         pre-trained teacher models
        :param kd_ensemble_weights: List of weights to apply to each teacher model
                                during distillation.
                                If the total is > 1 the loss will be scaled out
                                of proportion, acting in practice as a scaling factor
                                to the learning rate (the equivalence is true
                                in the composite loss model, and only approximate
                                for the regular distillation model. Scaling the
                                softmax out of proportion creates a target that
                                is impossible to reach, since the output distribution
                                can only sum to 1)
        :param kd_factor_init: Determines the percentage of the target that comes
                            from the teacher model. Value should be float
                            between 0 and 1. Defaults to 1.
        :param kd_factor_end: KD factor at last epoch. Will calculate linear decay
                            based on initial kd_factor_init and kd_factor_end.
                            Value should be float between 0 and 1.
                            If None, no decay is applied. Defaults to None.
        :param kd_temperature_init: Determines the temperature T applied to softmax.
                                If T > 1, it smoothes the softmax distribution.
                                If T < 1, it sharpens the distribution (more mass to
                                few points). If kd_temperature_end is also defined,
                                this variable equals the temperature at the beginning
                                of training. Defaults to 1.0
        :param kd_temperature_end: Determines the temperature applied to softmax.
                                Will calculate linear decay based on
                                kd_temperature_init and kd_temperature_end.
                                If None, no decay is applied. Defaults to None.
        """

        super().__init__(*args, **kwargs)

        mixin_args = self.args.trainer_mixin_args

        teacher_names_or_paths = mixin_args.get("teacher_model_names_or_paths", None)
        teacher_models_cache_dir = mixin_args.get("teacher_models_cache_dir", None)
        kd_ensemble_weights = mixin_args.get("kd_ensemble_weights", None)
        kd_factor_init = mixin_args.get("kd_factor_init", 1.0)
        kd_factor_end = mixin_args.get("kd_factor_end", 1.0)
        kd_temperature_init = mixin_args.get("kd_temperature_init", 1.0)
        kd_temperature_end = mixin_args.get("kd_temperature_end", 1.0)

        # Validate teacher models
        assert (
            isinstance(teacher_names_or_paths, list) and len(teacher_names_or_paths) > 0
        ), "When using KD mixin, teacher_model_names_or_paths must be defined"

        teacher_models = []
        for model_name_or_path in teacher_names_or_paths:
            teacher_model = AutoModelForMaskedLM.from_pretrained(
                model_name_or_path,
                cache_dir=teacher_models_cache_dir
            )
            teacher_model.resize_token_embeddings(len(self.tokenizer))
            teacher_models.append(teacher_model)

        if len(teacher_models) == 1:
            logging.info(f"KD single teacher class: {teacher_models.__class__}")
        else:
            logging.info(f"KD teacher is ensemble of {len(teacher_models)} models")

        seq_length = get_model_seq_length(self.model)
        self.teacher_models = [
            resize_position_embeddings(model, seq_length).eval().to(self.args.device)
            for model in teacher_models
        ]

        # Validate knowledge Distillation factor
        assert 0 <= kd_factor_init <= 1, "kd_factor_init should be >= 0 and <= 1"
        assert 0 <= kd_factor_end <= 1, "kd_factor_end should be >= 0 and <= 1"
        logging.info(f"KD factor: {kd_factor_init} {kd_factor_end}")

        # Validate Knowledge softmax temperature factor
        logging.info(
            f"KD softmax temperature: {kd_temperature_init} {kd_temperature_end}"
        )

        # Validate ensemble weighting
        num_models = len(teacher_models)
        if kd_ensemble_weights is None:
            kd_ensemble_weights = [1.0 / num_models for _ in range(num_models)]
        else:
            assert (
                len(kd_ensemble_weights) == num_models
            ), "Number of ensemble weights should match number of teacher models"
        logging.info(f"Ensemble weights: {kd_ensemble_weights}")

        # Initialize KD as a label smoother
        self.label_smoother = KDLoss(
            num_classes=list(self.model.parameters())[-1].size()[0],
            kd_ensemble_weights=kd_ensemble_weights,
            kd_factor_init=kd_factor_init,
            kd_factor_end=kd_factor_end,
            kd_temperature_init=kd_temperature_init,
            kd_temperature_end=kd_temperature_end,
        )

    def activate_distillation(self):
        self.kd_active = True

    def deactivate_distillation(self):
        self.kd_active = False

    def train(self, *args, **kwargs):
        self.activate_distillation()
        return super().train(*args, **kwargs)

    def evaluate(self, *args, **kwargs):
        self.deactivate_distillation()
        return super().evaluate(*args, **kwargs)

    def predict(self, *args, **kwargs):
        self.deactivate_distillation()
        return super().predict(*args, **kwargs)

    def compute_loss(self, model, inputs, return_outputs=False):
        """
        Override original compute_loss.
        KDLoss is used as a label smoother.
        Defaults to standard loss calculation if kd_active is False

        Original: how the loss is computed by Trainer. By default, all models return
        the loss in the first element.
        """
        if self.kd_active and "labels" in inputs:
            labels = inputs.pop("labels")
        else:
            labels = None

        # main model output
        outputs = model(**inputs)

        # Save past state if it exists (block kept from original function)
        # TODO: this needs to be fixed and made cleaner later.
        if self.args.past_index >= 0:
            self._past = outputs[self.args.past_index]

        if self.kd_active and labels is not None:
            # distillation outputs
            with torch.no_grad():
                teacher_outputs = [teacher(**inputs) for teacher in self.teacher_models]
            loss = self.label_smoother(
                model_output=outputs,
                teacher_outputs=teacher_outputs,
                labels=labels,
                trainer_state=self.state
            )
        else:
            # don't use .loss here since model may return tuples instead of ModelOutput.
            loss = outputs["loss"] if isinstance(outputs, dict) else outputs[0]

        return (loss, outputs) if return_outputs else loss

class KDLoss:
    """
    Calculates knowledge distillation loss. To be used in place of label smoother

    :param num_classes: Number of units in the output layer.
    :param kd_ensemble_weights: List of weights to apply to each teacher model
                                during distillation.
                                If the total is > 1 the loss will be scaled out
                                of proportion, acting in practice as a scaling factor
                                to the learning rate (the equivalence is true
                                in the composite loss model, and only approximate
                                for the regular distillation model. Scaling the
                                softmax out of proportion creates a target that
                                is impossible to reach, since the output distribution
                                can only sum to 1)
    :param kd_factor_init: Determines the percentage of the target that comes
                           from the teacher model. Value should be float
                           between 0 and 1. Defaults to 1.
    :param kd_factor_end: KD factor at last epoch. Will calculate linear decay
                          based on initial kd_factor_init and kd_factor_end.
                          Value should be float between 0 and 1.
                          If None, no decay is applied. Defaults to None.
    :param kd_temperature_init: Determines the temperature T applied to softmax.
                                If T > 1, it smoothes the softmax distribution.
                                If T < 1, it sharpens the distribution (more mass to
                                few points). If kd_temperature_end is also defined,
                                this variable equals the temperature at the beginning
                                of training. Defaults to 1.0
    :param kd_temperature_end: Determines the temperature applied to softmax.
                               Will calculate linear decay based on
                               kd_temperature_init and kd_temperature_end.
                               If None, no decay is applied. Defaults to None.
    :param verbose: Whether or not to log information on temperature and factor decay
    """

    def __init__(
        self,
        num_classes,
        kd_ensemble_weights,
        kd_factor_init,
        kd_factor_end,
        kd_temperature_init,
        kd_temperature_end,
        verbose=True,
    ):
        self.num_classes = num_classes
        self.kd_ensemble_weights = kd_ensemble_weights
        self.kd_factor_init = kd_factor_init
        self.kd_factor_end = kd_factor_end
        self.kd_temperature_init = kd_temperature_init
        self.kd_temperature_end = kd_temperature_end
        self.verbose = verbose
        self.loss_fn = masked_soft_cross_entropy
        self.ignore_index = -100

    def compute_kd_factor(self, trainer_state):
        """Calculates kd factor based on a linear decay"""
        kd_factor = calculate_linear_decay(
            first_step_value=self.kd_factor_init,
            last_step_value=self.kd_factor_end,
            current_step=trainer_state.global_step,
            total_steps=trainer_state.max_steps,
        )
        if self.verbose and (
            (trainer_state.global_step / trainer_state.max_steps) % 0.1 == 0
        ):
            logging.debug(
                f"KD factor: {kd_factor:.3f} "
                f"@ step {trainer_state.global_step}"
            )
        return kd_factor

    def compute_kd_temperature(self, trainer_state):
        """Calculates softmax temperature based on a linear decay"""
        kd_temperature = calculate_linear_decay(
            first_step_value=self.kd_temperature_init,
            last_step_value=self.kd_temperature_end,
            current_step=trainer_state.global_step,
            total_steps=trainer_state.max_steps,
        )
        if self.verbose and (
            (trainer_state.global_step / trainer_state.max_steps) % 0.1 == 0
        ):
            logging.debug(
                f"KD temperature: {kd_temperature:.3f} "
                f"@ step{trainer_state.global_step}"
            )

        return kd_temperature

    def __call__(self, model_output, teacher_outputs, labels, trainer_state):

        # Compute KD factor and temperature according to current step
        kd_factor = self.compute_kd_factor(trainer_state)
        kd_temperature = self.compute_kd_temperature(trainer_state)

        def get_logits(output):
            return output["logits"] if isinstance(output, dict) else output[0]

        student_logits = get_logits(model_output)

        with torch.no_grad():
            # If ensemble, linearly combine outputs of softmax
            softmax_output_teacher = None
            for w_factor, t_output in zip(self.kd_ensemble_weights, teacher_outputs):
                teacher_logits = get_logits(t_output)
                if softmax_output_teacher is None:
                    softmax_output_teacher = \
                        F.softmax(teacher_logits / kd_temperature, dim=-1) * w_factor
                else:
                    softmax_output_teacher += (
                        F.softmax(teacher_logits / kd_temperature, dim=-1) * w_factor
                    )

            # Replace labels according to kd_factor
            # if conditional avoids unnecessary computation when kd_factor is 1
            # TODO: fix bug in output combination
            if kd_factor < 1:
                # target is linear combination of teacher and target softmaxes
                ohe_target = F.one_hot(labels, num_classes=self.num_classes)
                kd_target = (
                    kd_factor * softmax_output_teacher + (1 - kd_factor) * ohe_target
                )
            else:
                kd_target = softmax_output_teacher

        # calculate padding mask
        if labels.dim() == kd_target.dim() - 1:
            labels = labels.unsqueeze(-1)
        padding_mask = labels.eq(self.ignore_index)

        loss = self.loss_fn(
            output=student_logits,
            target=kd_target,
            padding_mask=padding_mask
        )

        return loss

def soft_cross_entropy(output, target, reduction="mean"):
    """ Cross entropy that accepts soft targets
    Args:
    :param output: predictions for neural network
    :param targets: targets, can be soft
    :param size_average: if false, sum is returned instead of mean

    Examples::

        output = torch.FloatTensor([[1.1, 2.8, 1.3], [1.1, 2.1, 4.8]])
        output = torch.autograd.Variable(out, requires_grad=True)

        target = torch.FloatTensor([[0.05, 0.9, 0.05], [0.05, 0.05, 0.9]])
        target = torch.autograd.Variable(y1)
        loss = cross_entropy(output, target)
        loss.backward()

    see: https://discuss.pytorch.org/t/cross-entropy-with-one-hot-targets/13580/5
    """
    if reduction == "mean":
        return torch.mean(torch.sum(-target * F.log_softmax(output, dim=1), dim=1))
    elif reduction == "sum":
        return torch.sum(torch.sum(-target * F.log_softmax(output, dim=1), dim=1))
    else:
        raise ValueError(f"Unknown reduction: {reduction}")

def masked_soft_cross_entropy(output, target, padding_mask):
    """
    Soft cross entropy which accepts a padding mask. Loss is scaled to take into
    account the actual number of elements used to calculate the loss.

    Args:
    :param output: predictions for neural network
    :param targets: targets, can be soft
    :param padding_mask: mask used to pad loss functions for tokens which are not
                         part of the label for that batch
    """
    loss_vec = -target * F.log_softmax(output, dim=-1)
    loss_vec.masked_fill_(padding_mask, 0.0)
    loss = loss_vec.sum()
    num_active_elements = padding_mask.numel() - padding_mask.sum()
    return loss / num_active_elements

def calculate_linear_decay(
    first_step_value, last_step_value, current_step, total_steps
):
    """
    Calculates value for a current step in a linear decay.

    :param first_step_value: Value at first step (before training).
    :param last_step_value: Value at last step (after training).
    :param current_step: Current step. Assumes first step is 0.
    :param total_steps: Total number of steps in training.
    """
    step_size = (first_step_value - last_step_value) / (total_steps - 1)
    return first_step_value - step_size * current_step

def resize_position_embeddings(model, new_seq_length):
    """
    Resizes model's position embeddings matrices if the size of max position embedding
    doesn't match new sequence length.
    (size of position embedding equals size of the attention window)

    :param new_seq_length: Tokenizer sequence length.
    """

    position_embeddings = filter_modules(
        model, include_patterns=[".*position_embeddings.*"]
    )
    for module_name, module in position_embeddings.items():
        original_embed_data = module.weight.data
        max_position_embeddings, embed_hidden_size = original_embed_data.size()
        if max_position_embeddings != new_seq_length:
            new_embed = torch.nn.Embedding(new_seq_length, embed_hidden_size)
            new_embed.weight.data[:, :] = original_embed_data[:new_seq_length, :]
            set_module_attr(model, module_name, new_embed)

    return model

def get_model_seq_length(model):
    """
    Returns size of seq length according to first found position embedding in model
    """
    for module_name, module in model.named_modules():
        if "position_embeddings" in module_name:
            return module.weight.data.size()[0]


#Working with file IO before doing anything with loops feelsweirdman
from sys import argv

#get the name of the file we are reading from the command line argument
script, filename = argv

#opens the file with name given as an argument in the command line
txt = open(filename)

print (f"Here are the contents of the file {filename}:\n")
#Calls the read function with the opened file in order to display its contents
print (txt.read())
txt.close()

print ("\nType the file name again please: ")
file_again = input ("> ")
txt_again = open(file_again)
print (txt_again.read())
txt_again.close()


from pyspark import SparkConf, SparkContext
import sys
import json                       #Added
assert sys.version_info >= (3, 5) # make sure we have Python 3.5+
from operator import is_not
from functools import partial
# add more functions as necessary

def add_pairs(x,y):
    (a,b) = x
    (c,d) = y
    return (a+c,b+d)

def key_value(text):
    key = text.get("subreddit")  #subreddit as key
    val1 = text.get("score")     #count, score_sum pair as value
    count=1
    return(key,(val1,count))

def avg_score(xyz):
    x,(y,z) = xyz
    a_score = float(y/z)
    return (x,a_score)

def split(text):
    subreddit = text.get("subreddit")  #subreddit as key
    score = text.get("score")     #count, score_sum pair as value
    author=text.get("author")
    transform = {"author": author, "subreddit": subreddit,"score":score}
    return transform
def search(text):
    s=text.get("subreddit")
    score = text.get("score")     #count, score_sum pair as value
    author=text.get("author")
    if 'e' in s:
            transform = {"author": author, "subreddit": s,"score":score}
            return transform

def main(inputs, output):
    text = sc.textFile(inputs)
    outdata = text.map(json.loads)
    #outdata.saveAsTextFile(output)
    new=outdata.map(search)
    new = new.filter(partial(is_not, None))
    #new.saveAsTextFile(output)
    new_out=new.map(key_value)
    #new_out.saveAsTextFile(output)
    f_out=new_out.reduceByKey(add_pairs).cache()
    f2_out=f_out.map(avg_score)
    #f2_out.saveAsTextFile(output+'/3')

    f3_out=f2_out.filter(lambda n:n[1]>0)
    f3_out.map(json.dumps).saveAsTextFile(output + '/positive')
    f4_out=f2_out.filter(lambda n:n[1]<=0)
    f4_out.map(json.dumps).saveAsTextFile(output + '/negative')

    #f3_out.saveAsTextFile(output)
if __name__ == '__main__':
    conf = SparkConf().setAppName('reddit average code')
    sc = SparkContext(conf=conf)
    assert sc.version >= '2.3'  # make sure we have Spark 2.3+
    inputs = sys.argv[1]
    output = sys.argv[2]
    main(inputs, output)

#-------------------------------------------------------------------------------------------------


#!/usr/bin/env python3

import nmap
import sys

class NETWORK_ENUMERATION():
		def __init__(self):
			dgate = input("Enter IPv4 default gateway in decimal notation: ")
			subnet = int(input("Enter the subnet mask in CIDR notation: /"))
			self.dgate = dgate
			self.subnet = subnet

		def host_discovery(self):
			""" Prints to stdout hosts on a network given a default gateway IPv4 adddress and subnet mask in CIDR notation.
			Makes use of nmap's 'sn' option.
			'sn' option: 'tells Nmap not to do a port scan after host discovery, and only print /n
			out the available hosts that responded to the scan.' """

			# Ensuring user cannot enter a defualt gateway that is longer than the max length of an IPv4 address in decimal notaion, 15 characters.
			# Ensuring user cannot enter a subnet mask that is greater than the value /32.
			if len(self.dgate) > 15 or self.subnet >= 32:
				print("# Enter a correct default gateway!")
				print("# Subnet mask cannot exceed 31 bits!")
				print("# Gracefully exiting...")
				sys.exit(0)
			else:
				# typecast subnet mask into str as you can't concetante type int
				network = self.dgate + "/" + str(self.subnet)
				print("# Scanning network for available hosts...")

				# nmap object
				nm = nmap.PortScanner()
				# scanning network for hosts "sn" argument is the nmap option used to perform a scan
				nm.scan(hosts=network, arguments="sn")
				# using list comprehension to output available hosts on the network
				available_hosts = [(host, nm[host]["status"]["state"]) for host in nm.all_hosts()]

				for host, status in available_hosts:
					print(f"Hosts\t{host}")

if __name__ == "__main__":
	scan = NETWORK_ENUMERATION()
	scan.host_discovery()


#PROBLEMS 4: find the largest palindrome made from the product of two 3-digit numbers

pal = 0

def checkPal(n):
	m = str(n)
	if m == m[::-1]:
		return True
	else:
		return False

for i in range(100, 1000):
    for j in range(100, 1000):
        k = i*j
        if checkPal(k) and k > pal:
            pal = k

print(pal)


"""
"""

from collections import OrderedDict as OD
import re

import sympy
import numpy as np

from SloppyCell.ReactionNetworks.Reactions import Reaction

from util2 import butil
reload(butil)

def get_substrates(stoich, multi=False):
    """
    Input:
        multi:
    """
    for spid, stoichcoef in stoich.items():
        # could be ...
        stoichcoef = int(float(stoichcoef))

    subs = [[spid]*abs(int(float(stoichcoef))) for (spid, stoichcoef)
            in stoich.items() if stoichcoef<0]
    subs = butil.flatten(subs)
    if not multi:
        subs = list(set(subs))
    subs = sorted(subs)  # make spids appear in order
    return subs

def get_products(stoich, multi=False):
    pros = [[spid]*abs(stoichcoef) for (spid, stoichcoef)
            in stoich.items() if stoichcoef>0]
    pros = butil.flatten(pros)
    if not multi:
        pros = list(set(pros))
    pros = sorted(pros)  # make spids appear in order
    return pros

def get_reactants(stoich, multi=True):
    """
    Sometimes a stoichiometry has species that are not reactants, whose
    stoichiometry coefficients are zero.
    """
    return get_substrates(stoich, multi) + get_products(stoich, multi)

def get_merged_stoich(*stoichs):
    """
    """
    spids = sorted(set(butil.flatten([stoich.keys() for stoich in stoichs])))
    stoich_m = type(stoichs[0]).fromkeys(spids, 0)
    for stoich in stoichs:
        for spid, stoichcoef in stoich.items():
            stoich_m[spid] += stoichcoef
    for spid, stoichcoef in stoich_m.items():
        if stoichcoef == 0:
            del stoich_m[spid]
    return stoich_m

def reverse_stoich(stoich):
    """

    """
    stoich_b = type(stoich).fromkeys(stoich.keys(), 0)  # b for backward
    for spid, stoichcoef in stoich.items():
        stoich_b[spid] = -1 * stoichcoef
    return stoich_b

def get_all_states(spids):
    """
    """
    states = butil.get_powerset(spids)
    states_sort = sorted([tuple(sorted(s)) for s in states])
    return states_sort

def stoich2eqn(stoich):
    pass

def eqn2stoich(eqn):
    """
    Convert reaction equation (a string) to stoichiometry (a dictionary).
    """
    def unpack(s):
        # an example of s: ' 2 ATP '
        l = filter(None, s.split(' '))
        if len(l) == 1:
            stoichcoef, spid = '1', l[0]
        if len(l) == 2:
            stoichcoef, spid = l
        return spid, stoichcoef

    # re: '<?': 0 or 1 '<'; '[-|=]': '-' or '='
    subs, pros = re.split('<?[-|=]>', eqn)
    stoich = OD([])

    for sub in subs.split('+'):
        subid, stoichcoef = unpack(sub)
        stoich[subid] = '-' + stoichcoef
    for pro in pros.split('+'):
        proid, stoichcoef = unpack(pro)
        stoich[proid] = stoichcoef

    return stoich

def get_ratelaw_MM(rxnid, stoich, reversible=True,
                   Keq=None, KIcs=None, KIus=None, KAs=None,
                   states_allowed=None, states_add=None, one_step=False):
    """
    Construct rate law expressions for Michaelis-Menten kinetics
    with quasi-equilibrium assumption.

    Input:
        stoich: a dict mapping from species ids to stoich coefs,
                e.g., {'S':-1, 'P':1, 'I':0}
        Keq: a number, e.g., 1e2
        KIcs: a dict mapping from ids of competitive inhibitors to
              inhibition constants,
              e.g., {'I1':2.5e-2, 'I2':1e-1}
        KIus: a dict mapping from ids of uncompetitive inhibitors to
              inhibition constants,
              e.g., {'I1':2.5e-2, 'I2':1e-1}
        states_allowed: a list of tuples, orders not matter
        one_step: one step binding used by Alex Shestov; if True, assume...

    Output:

    """
    # Abbreviations:
    # sub: substrate
    # pro: product
    # s: state
    # f: forward
    # b: backward

    subs = get_substrates(stoich, multi=True)
    pros = get_products(stoich, multi=True)
    #state_allsubs = tuple(subs)
    #state_allpros = tuple(pros)
    KMs_sub = ['KM_%s_%s'%(rxnid, sub) for sub in subs]
    KMs_pro = ['KM_%s_%s'%(rxnid, pro) for pro in pros]
    spid2KM = dict(zip(subs+pros, KMs_sub+KMs_pro))

    # make a dictionary, state2term, that maps from binding state
    # of the enzyme to the corresponding term
    states = [()]
    if one_step:
        states.append(tuple(subs))
        states.append(tuple(pros))
    elif states_allowed:
        states.extend(states_allowed)
    else:
        states.extend(get_all_states(subs)+get_all_states(pros))
    if states_add:
        states.extend(states_add)
    # remove duplicates and double sort
    states = sorted(set([tuple(sorted(s)) for s in states]))

    state2term = OD([((), '1')])
    for state in states:
        term = '*'.join(['(%s/%s)'%(spid, spid2KM[spid]) for spid in state])
        if term == '':
            term = '1'
        term = str(sympy.simplify(term))
        state2term[state] = term
    if one_step:
        state2term[tuple(subs)] = '%s/KM_%s_f'%('*'.join(subs), rxnid)
        state2term[tuple(pros)] = '%s/KM_%s_b'%('*'.join(pros), rxnid)

    if KIcs:  # add the competitive-inhibitor bound states
        for spid in KIcs.keys():
            term = '(%s/KIc_%s_%s)'%(spid, rxnid, spid)
            state2term[tuple([spid])] = term

    #for (state, term) in state2term.items():
    #    state2term[state] = str(sympy.simplify(term))

    Vf, Vb = 'Vf_%s'%rxnid, 'Vb_%s'%rxnid
    if Keq:  # use Haldane's relation to cancel Vb
        # Haldane's relation says at equilibrium:
        # Vf*subs/KMs_sub = Vb*pros/KMs_pro; therefore:
        # pros/subs = Keq = Vf*KMs_pro/(Vb*KMs_sub),
        # Vb = Vf*KMs_pro/(KMs_sub*Keq)
        Keq = 'Keq_%s'%rxnid
        if one_step:
            KMs_f = 'KM_%s_f'%rxnid
        else:
            KMs_f = '(' + '*'.join(KMs_sub) + ')'
        numerator = '(%s/%s*(%s-%s/%s))'%(Vf, KMs_f, '*'.join(subs),
                                          '*'.join(pros), Keq)
    else:
        numerator = '(%s*%s - %s*%s)'%(Vf, state2term[tuple(subs)],
                                       Vb, state2term[tuple(pros)])
    if not reversible:
        numerator = '(%s*%s)'%(Vf, state2term[tuple(subs)])
    denominator = '(' + '+'.join(state2term.values()) + ')'
    ratelaw = '(%s/%s)'%(numerator, denominator)

    if KIus:
        for spid in KIus.keys():
            term = '%s/KIu_%s_%s'%(spid, rxnid, spid)
            ratelaw = '%s*(1/(1+%s))'%(ratelaw, term)
    if KAs:
        for spid in KAs.keys():
            term = '%s/KA_%s_%s'%(spid, rxnid, spid)
            ratelaw = '%s*(%s/(1+%s))'%(ratelaw, term, term)

    return ratelaw

def add_reaction_MM(net, id, Vs, stoich, KMs, reversible=True,
                    Keq=None, deltaG=None, KIcs=None, KIus=None, KAs=None,
                    one_step=False, duplicate_error=True,
                    param_optimizable=True,
                    states_allowed=None, states_add=None):
    """
    Requires the species to be in the network
    """
    rxnid = id

    # check if the species are already in the network

    # add the parameters
    for direction, paramval in Vs.items():
        if isinstance(paramval, tuple):
            paramval = paramval[0]
        paramid = 'V' + direction + '_' + rxnid
        net.add_parameter(paramid, paramval, is_optimizable=True)
    if Keq or deltaG is not None:
        if deltaG is not None:
            R = 8.314
            T = 310.15  # 273.15+37
            Keq = np.exp(-deltaG * 1e3 / R / T)
        #if isinstance(Keq, tuple):
        #    paramval = Keq[0]
        net.add_parameter('Keq_'+rxnid, Keq, is_optimizable=False)
    for spid, paramval in KMs.items():
        if isinstance(paramval, tuple):
            paramval = paramval[0]
        paramid = 'KM_' + rxnid + '_' + spid
        net.add_parameter(paramid, paramval, is_optimizable=True)
    if KIcs is not None:
        for spid, paramval in KIcs.items():
            if isinstance(paramval, tuple):
                paramval = paramval[0]
            paramid = 'KIc_' + rxnid + '_' + spid
            net.add_parameter(paramid, paramval, is_optimizable=True)
    if KIus is not None:
        for spid, paramval in KIus.items():
            if isinstance(paramval, tuple):
                paramval = paramval[0]
            paramid = 'KIu_' + rxnid + '_' + spid
            net.add_parameter(paramid, paramval, is_optimizable=True)
    if KAs is not None:
        for spid, paramval in KAs.items():
            if isinstance(paramval, tuple):
                paramval = paramval[0]
            paramid = 'KA_' + rxnid + '_' + spid
            net.add_parameter(paramid, paramval, is_optimizable=True)

    # get the rate law
    ratelaw = get_ratelaw_MM(rxnid=rxnid, stoich=stoich, reversible=reversible,
                             one_step=one_step, Keq=Keq,
                             KIcs=KIcs, KIus=KIus, KAs=KAs,
                             states_allowed=states_allowed,
                             states_add=states_add)
    # add the reaction
    net.addReaction(rxnid, stoich, kineticLaw=ratelaw)
    net.reactions.get(rxnid).kinetics = 'MichaelisMenten'

def add_reaction_SMM(net, id, Vs, stoich_or_eqn, KMs, reversible=True,
                     Keq=None, deltaG=None, KIcs=None, KIus=None, KAs=None,
                     duplicate_error=True, param_optimizable=True):
    """
    SMM: standard Michaelis-Menten kinetics, referring to quasi-equilibrium
         and random-order assumptions
    """
    if isinstance(stoich_or_eqn, 'str'):
        stoich = eqn2stoich(stoich_or_eqn)
    else:
        stoich = stoich_or_eqn

def add_transport_MM(net, rxnid, stoich, V, KM, reversible=True):
    """
    Transporter of Michaelis-Menten kinetics with the same V and KM.
    """
    id_V = 'V_' + rxnid
    id_sub = get_substrates(stoich, multi=False)[0]
    id_pro = get_products(stoich, multi=False)[0]
    spid = min([id_sub, id_pro], key=len)  # the shorter one is the spid
    id_KM = 'KM_%s_%s'%(rxnid, spid)
    if reversible:
        ratelaw = '%s/%s*(%s-%s)/(1+%s/%s+%s/%s)'%(id_V, id_KM, id_sub, id_pro,
                                                   id_sub, id_KM, id_pro, id_KM)
    else:
        raise NotImplementedError
        # there is no id_pro
        #ratelaw = '%s*%s/%s/(1+%s/%s)'%(id_V, id_sub, id_KM, id_sub, id_pro)
    net.add_parameter(id_V, V, is_optimizable=True)
    net.add_parameter(id_KM, KM, is_optimizable=True)
    net.addReaction(rxnid, stoich, kineticLaw=ratelaw)

def get_ratelaw_MA(rxnid, stoich, reversible, Keq):
    subs = get_substrates(stoich, multi=True)
    prods = get_products(stoich, multi=True)
    kf = 'kf_' + rxnid
    kb = 'kb_' + rxnid
    if Keq:
        Keq = 'Keq_' + rxnid
    if not reversible:
        ratelaw = '%s*%s' % (kf, '*'.join(subs))
    else:
        if Keq:
            kb = '(%s/%s)' % (kf, Keq)
        ratelaw = '%s*%s-%s*%s' % (kf, '*'.join(subs),
                                   kb, '*'.join(prods))
    return ratelaw

def add_reaction_MA(net, id, ks, stoich, reversible=True, Keq=None,
                    duplicate_error=True):
    """
    """
    rxnid = id

    # check if the species are already in the network
    for spid in stoich.keys():
        if spid not in net.species.keys():
            raise StandardError("Error when adding reaction %s:\
                                 species %s has not been added yet."
                                    % (rxnid, spid))
    # add the parameters
    for direction, paramval in ks.items():
        if isinstance(paramval, tuple):
            paramval = paramval[0]
        paramid = 'k' + direction + '_' + rxnid
        net.add_parameter(paramid, paramval, is_optimizable=True)
    if Keq:
        net.add_parameter('Keq_'+rxnid, Keq, is_optimizable=False)
    # get the rate law
    ratelaw = get_ratelaw_MA(rxnid=rxnid, stoich=stoich,
                             reversible=reversible, Keq=Keq)
    # add the reaction
    net.addReaction(rxnid, stoich, kineticLaw=ratelaw)
    net.reactions.get(rxnid).kinetics = 'MassAction'

def get_ratelaw_MWC():
    pass

def add_reaction_MWC():
    pass

class IrreversibleMultisubstrateMichaelisMenten(Reaction):
    """

    """

    def __init__(self, id, stoichiometry, info_inhibitors=None, activators=None):
        """
        Parameters
        ----------
        info_inhibitors, a dict
            example:
            [{'inhibitor': 'I1', 'substrate': 'S1', 'mode': 'competitive'},
             {'inhibitor': 'I1', 'substrate': 'S1', 'mode': 'uncompetitive'},
             {'inhibitor': 'I2', 'substrate': 'S2', 'mode': 'competitive'},
             {'inhibitor': 'I3', 'substrate': 'S1', 'mode': 'competitive'}
            ]
            Let:
                id = 13
                substrates = ['S1', 'S2']
            Then:
                kineticLaw = 'Vm_13*S1*S2/((Km_13_S1*(1+I1/Kic_13_S1_I1+I3/Kic_13_S1_I3)+
                              S1*(1+I1/Kiu_13_S1_I1))*(Km_13_S2*(1+I2/Kic_13_S2_I2)+S2))'
        activators, a dict
            example: to be implemented.
        """
        str_Vm = 'Vm_' + id
        substrates = get_substrates(stoichiometry)
        kineticLaw_numerator = str_Vm + '*' + '*'.join(substrates)
        kineticLaw_denominator_components = []
        for substrate in substrates:
            str_Km = 'Km_' + id + '_' + substrate
            str_concn = substrate
            if info_inhibitors:  # if the reaction has inhibitors
                for info in info_inhibitors:
                    if isinstance(info, tuple):
                        inhibitor, substrate_inhibited, mode = info
                    else:
                        substrate_inhibited = info['substrate']
                        inhibitor = info['inhibitor']
                        mode = info['mode']
                    if substrate == substrate_inhibited:
                        if mode == 'competitive' or mode == 'c':
                            str_Ki = 'Kic_' + id + '_' + substrate + '_' + inhibitor
                            if not str_Km.endswith(')'):
                                str_Km = str_Km + '*(1+' + inhibitor + '/' +  str_Ki + ')'
                            else:
                                str_Km = str_Km[:-1] + '+' + inhibitor + '/' + str_Ki + ')'
                        else:  # uncompetitive inhibition
                            str_Ki = 'Kiu_' + id + '_' + substrate + '_' + inhibitor
                            if not str_concn.endswith(')'):
                                str_concn = str_concn + '*(1+' + inhibitor + '/' +  str_Ki + ')'
                            else:
                                str_concn = str_concn[:-1] + '+' + inhibitor + '/' + str_Ki + ')'
            else:  # if the reaction has no inhibitors
                pass
            kineticLaw_denominator_components.append('('+str_Km+'+'+str_concn+')')
        kineticLaw_denominator = '*'.join(kineticLaw_denominator_components)
        kineticLaw = kineticLaw_numerator + '/(' + kineticLaw_denominator + ')'
        Reaction.__init__(self, id, stoichiometry, kineticLaw)

class ReversibleMassAction(Reaction):
    """
    """
    def __init__(self, id, stoichiometry):
        """
        """
        str_substrates = '*'.join(['pow('+sp+','+str(abs(stoichiometry[sp]))+')'
                                   for sp in stoichiometry.keys() if stoichiometry[sp]<0])
        str_products = '*'.join(['pow('+sp+','+str(stoichiometry[sp])+')'
                                 for sp in stoichiometry.keys() if stoichiometry[sp]>0])
        kineticLaw = 'k_'+id+'*('+str_substrates+'-'+str_products+'/'+'Ke_'+id+')'
        Reaction.__init__(self, id, stoichiometry, kineticLaw)

def add_diseq_variables(net, rxnid2dG0=None,
                        add_Q=False, add_dG=False, add_g=True,
                        skip_no_dG0=True, T=25):
    """
    Add disequilibrium variables

    dG = deltaG
    dG0 = deltaG0
    g = dG/RT
    g0 = dG0/RT

    Input:
        T: temperature in celsius degrees (~25 for room temperature and ~37 for
            human body)

    """
    net = net.copy()

    for rxnid, rxn in net.reactions.items():
        subs = get_substrates(rxn.stoichiometry)
        pros = get_products(rxn.stoichiometry)
        str_sub = '*'.join(subs)
        str_pro = '*'.join(pros)
        str_Q = '(%s)/(%s)' % (str_pro, str_sub)
        id_Q = 'Q_' + rxnid

        if add_Q:
            net.add_parameter(id_Q)
            net.add_assignment_rule(id_Q, str_Q)

        RT = 8.315 * (T + 273.15) / 1000
        ## get deltaG0 (G0)
        if rxnid2dG0 and rxnid in rxnid2dG0:
            dG0 = rxnid2dG0[rxnid]
        elif hasattr(rxn, 'deltaG0'):
            dG0 = rxn.deltaG0
        elif hasattr(rxn, 'dG0'):
            dG0 = rxn.dG0
        else:
            if skip_no_dG0:
                continue
            else:
                raise Exception("deltaG0 for rxn %s undefined." % rxnid)

        if add_dG:
            id_dG = 'dG_' + rxnid
            if add_Q:
                str_dG = '%.3f + %.3f * log(%s)' % (dG0, RT, id_Q)
            else:
                str_dG = '%.3f + %.3f * log(%s)' % (dG0, RT, str_Q)
            net.add_parameter(id_dG)
            net.add_assignment_rule(id_dG, str_dG)

        if add_g:
            id_g = 'g_' + rxnid
            if add_Q:
                str_g = '%.3f + log(%s)' % (dG0/RT, id_Q)
            else:
                str_g = '%.3f + log(%s)' % (dG0/RT, str_Q)
            net.add_parameter(id_g)
            net.add_assignment_rule(id_g, str_g)

    return net


import os
import string
import subprocess

# SETTINGS
# --------
ALIGNMENTS = os.getcwd() + '/data/alignments/pcgita_words_read_mono.frame.ali_NEW'
OUTPUT = os.getcwd() + '/data/cut/'
ALPHABET = list(string.ascii_lowercase)
VOWELS = ['a', 'e', 'i', 'o', 'u', 'w'] # 'y' as vowel?

class ProcessAlignments():
    def __init__(self):
        self.alignments = os.getcwd() + '/data/alignments/pcgita_words_read_mono.frame.ali_NEW'
        self.output = os.getcwd() + '/data/cut/'

    def findTimeRanges(self, phones, letterType):
        startEndTimes = []

        i = 0
        while i < len(phones):
            currentLetter = phones[i][0]

            if (currentLetter in letterType):

                startIndex = i
                nextIndex = i + 1
                while (True):
                    if (nextIndex < len(phones)):
                        nextLetter = phones[nextIndex][0]
                        if (nextLetter == currentLetter):
                            nextIndex += 1
                        else:
                            startEndTimes.append((currentLetter, startIndex * 10, nextIndex * 10))
                            i = nextIndex
                            break
                    else:
                        i = nextIndex
                        startEndTimes.append((currentLetter, startIndex * 10, nextIndex * 10))
                        break

            elif phones[i] == 'SIL':
                startIndex = i
                nextIndex = i + 1
                while (True):
                    if (nextIndex < len(phones)):
                        nextWord = phones[nextIndex]
                        if (nextWord == 'SIL'):
                            nextIndex += 1
                        else:
                            startEndTimes.append(('SIL', startIndex * 10, nextIndex * 10))
                            i = nextIndex
                            break
                    else:
                        i = nextIndex
                        startEndTimes.append(('SIL', startIndex * 10, nextIndex * 10))
                        break
            i += 1

        return startEndTimes

    # Returns a dictionary of the start and end times to splice the .wav file.
    # {'001_monologue_' : [('a', 1000, 1010), ('b', 1020, 1030), ...], '002_monologue_': [('e', 1015, 1020), ('m', 1021, 1022), ...] }
    def getCutTimes(self, taskName, letterType):
        formantTimes = {}

        file = open(ALIGNMENTS, 'r')
        while (True):
            line = file.readline()
            if (not line): break
            if (line.find(taskName) >= 0):
                taskItem = line.split('PCGITA')
                filePrefix = taskItem[0] ## 001_monologue_
                phones = taskItem[1].split()

                formantTimes[filePrefix] = self.findTimeRanges(phones, letterType)

        file.close()
        return formantTimes

    def cutWavFiles(self, cutTimeRanges):
        for filePrefix in cutTimeRanges:
            cutTimes = cutTimeRanges[filePrefix]

            for i in range(len(cutTimes)):
                timeRange = cutTimes[i]

                letter = timeRange[0]
                start = timeRange[1] * 0.001
                end = timeRange[2] * 0.001

                inputWavName = filePrefix + 'PCGITA.wav'
                outputWavName = filePrefix + str(start) + '_' + str(end) + '_' + letter + '.wav'

                soxCommand = ['sox', os.getcwd()+'/data/audio/'+inputWavName , os.getcwd()+'/data/cut/'+outputWavName, 'trim', str(start), str(abs(start-end))]
                subprocess.call(soxCommand)

        print ('Done cutting wav files')

    # Produce strings with all the vowels as '*'s
    def produceStrings(self, cutTimeRanges):
        stringsToProcess = {}

        for filePrefix in cutTimeRanges:
            toProcess = ''
            ranges = cutTimeRanges[filePrefix]

            for element in ranges:
                letter = element[0]
                if letter in VOWELS: toProcess += '*'
                elif letter == 'k': toProcess += 'c'
                elif letter == 'SIL': toProcess += ' '
                # elif letter == 'w': toProcess += '*'
                else: toProcess += letter

            stringsToProcess[filePrefix] = toProcess

        return stringsToProcess
        print ('Done outputting strings')

# alignment = ProcessAlignments()

# monologueVowelCutTimes = alignment.getCutTimes('monologue', VOWELS)
# alignment.cutWavFiles(monologueVowelCutTimes)

# monologueAllCutTimes = alignment.getCutTimes('monologue', ALPHABET)
# alignment.produceStrings(monologueAllCutTimes)