import util
import logging
import re
import codecs
import shutil
import glob
import os
import urllib
from sub_task import SubTask

class InvalidFileDirectory(Exception):
    """
    Raised when the the user tries to use a file or directory that we cannot find

    Attributes:
        message  --
    """

    def __init__(self, message):
        self.message = 'Cannot find the file/directory specified. ' + message

    def __str__(self):
        return repr(self.message)

class Task:
    """
       Task constructor

       :param task_config
    """

    def __init__(self, parent, task_config):
        self.id = util.short_unique_id()
        self.__parent = parent
        self.name = task_config.get('taskName')
        self.description = task_config.get('taskDescription')
        self.wd = task_config.get('workingDir')
        self.wait = task_config.get('wait')
        self.fail_tolerant = task_config.get('failTolerant')
        self.__preparation = task_config.get('preparation')
        self.__commands = task_config.get('commands')
        self.__children = []
        logging.debug('Task - Created [%s] with ID [%s].', str(self.name), str(self.id))
        logging.debug('Task - Description [%s].', str(self.description))
        children_config = task_config.get('children')
        if children_config:
            for config in children_config:
                self.__children.append(Task(self, config))
        self.sub_tasks = []

    def get_sub_tasks(self):
        # ensure we just process this method once
        if self.sub_tasks:
            return self.sub_tasks
        if self.__preparation:
            pattern = r"{0}".format(urllib.unquote(self.__preparation.get('pattern')))
            # ok, lets see what we can do
            if self.__preparation.get('filterFile'):
                filter_file = self.__preparation.get('filterFile')
                write_file = self.__preparation.get('writeFile')
                placeholder = self.__preparation.get('placeholder')
                copy = self.__preparation.get('copy')
                filter_files_found = [name for name in glob.glob(filter_file)]
                write_files_found = [name for name in glob.glob(write_file)]
                if len(filter_files_found) < 1:
                    raise InvalidFileDirectory('Task - Files were not found matching {0}.'.format(filter_file))
                logging.debug('Task - Found [%s] file(s) to filter using [%s].', str(len(filter_files_found)), str(filter_file))
                if len(write_files_found) < 1:
                    raise InvalidFileDirectory('Task - Files were not found matching {0}.'.format(write_file))
                logging.debug('Task - Found [%s] file(s) to write using [%s].', str(len(write_files_found)), str(write_file))
                # ok, it seems we have a pattern, so we should look inside each file
                if pattern:
                    # look matching regex in each line of a file
                    all_matching_lines = self.__find_in_files(filter_files_found, pattern)
                    logging.debug('Task - Found [%s] matching result(s) using [%s].', str(len(all_matching_lines)), str(pattern))
                    # look matching regex in each line of each file
                    for w_file in write_files_found:
                        for line in filter(None, all_matching_lines):
                            new_file = w_file
                            if copy:
                                # create a copy of the file with the same name plus
                                new_file = self.__create_copy(w_file)

                            # get commands to execute
                            self.sub_tasks.append(self.__replace_in_commands(new_file, line))

                            # look in side the new file for the placeholder and replace it
                            self.__replace_in_file(new_file, placeholder, line)
                else:
                    # seems you just want to filter files, lets replace them in the commands
                    for f_file in filter_files_found:
                         self.sub_tasks.append(self.__replace_in_commands(f_file, f_file))
            else:
                raise Exception('Task - Oops this shouldn\'t happen!')

        else:
            sub_task = SubTask(self)
            sub_task.add_commands(self.__commands)
            self.sub_tasks.append(sub_task)
        logging.debug('Task - This Task has been splitted in [%s] Sub Task(s).', str(len(self.sub_tasks)))
        return self.sub_tasks

    """
        Utility method to copy files

        Returns the file name of the new file copied
    """

    def __create_copy(self, file):
        new_filename = '{0}-{1}-{2}'.format(self.name, util.short_unique_id(), os.path.basename(file))
        shutil.copy2(file, new_filename)
        return new_filename

    """
        Utility method to find certain pattern in a set of files

        Returns all matching results
    """

    def __find_in_files(self, files, pattern):
        all_matching_lines = []
        for file in files:
            with open(file, "r") as f:
                all_matching_lines.extend(re.findall(pattern, f.read(), re.MULTILINE))
                f.close()
        return all_matching_lines

    """
        Utility method to generate sub tasks

        Returns the new SubTask
    """

    def __replace_in_commands(self, file, line=''):
        sub_task = SubTask(self)
        for command in self.__commands:
            # replace placeholder with actual created file
            sub_task.add_command(command.replace('$file', file).replace('$line', line))
        return sub_task

    """
        Utility method to replace a placeholder with a value in a file
    """

    def __replace_in_file(self, file, placeholder, value):
        # look in side the new file for the placeholder and replace it
        with codecs.open(file, 'r', encoding='utf8') as fr:
            text = fr.read()
            fr.close()
        # replace placeholder
        text = text.replace(placeholder, str(value))
        with codecs.open(file, 'w', encoding='utf8') as fw:
            fw.write(text)
            fw.close()

    """
        Get Guidance Tasks

        :return tasks
    """

    def get_children(self):
        return self.__children

    """
        Returns True if there are Guidance Tasks
    """

    def has_children(self):
        return len(self.__children) > 0

    """
        Returns the parent task if this task is a child, otherwise None
    """

    def get_parent(self):
        return self.__parent

    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __hash__(self):
        return hash(self.name) ^ hash(self.name)


import pandas as pd
import os
import json
from collections.abc import Iterable

def read_json(path_to_json = 'data/input/'):
    """
       Reads jsons in the specified dir
        Parameters
        ----------
            path_to_json : string

        Returns
        -------
            List of jsons.
    """
    data = []
    for file_name in [file for file in os.listdir(path_to_json) if file.endswith('.json')]:
        with open(path_to_json + file_name) as json_file:
            data.append(json.load(json_file))
            return data

def parse_json_2_dataframe(jsons,unwanted_col = 'unwanted_col'):
    """
       Reads jsons in the specified dir
        Parameters
        ----------
            jsons : List of jsons.

            list_of_cols : list of columns from which DataFrame is made.

            unwanted_col : OPTIONAL, str.

            dataframe_aborted_cols : OPTIONAL, list of aborted columns

        Returns
        -------
            cleaned_dataframe : pd.DataFrame    N long table, N is number of episodes in the data.

            config_and_best : pd.DataFrame      table, with overall settings and best episode for each agent.
    """
    for json in jsons:
        list_of_cols = []
        dataframe_aborted_cols = []
        for key in json:
            if not isinstance(json[key], float):
                if key != unwanted_col:
                    col = pd.Series(json[key],name=key)
                    list_of_cols.append(col)
                else:
                    dataframe_aborted_cols.append(pd.Series(json[key],name=key))

        dataframe = pd.DataFrame(list_of_cols).T
        cleaned_dataframe = dataframe[['timestamps', 'episode_lengths', 'episode_rewards',
           'episode_winners', 'episode_types']].dropna(axis=0)
        config_and_best = dataframe[['episode_best','config']]
        return cleaned_dataframe, config_and_best

data, config_info = parse_json_2_dataframe(read_json())

def parse_episode_rewards(episode_reward):
    """
           Reads jsons in the specified dir
            Parameters
            ----------
                episode_reward : pd.Series  containing list of lists

            Returns
            -------
                sum(seeker_sum) : int   sum of seeker rewards

                sum(hiding_sum) : int      sum of hiding rewards
        """
    seeker_sum, hiding_sum = [], []
    for frame in episode_reward:
        for seeker_reward, hiding_reward in frame:
            seeker_sum.append(seeker_reward)
            hiding_sum.append(hiding_reward)
    return sum(seeker_sum), sum(hiding_sum)

data.episode_rewards = [parse_episode_rewards(episode_reward) for episode_reward in zip(data.episode_rewards)]
agents_rewards = data.episode_rewards.apply(pd.Series)
data['seeker_rewards'] = agents_rewards[0]
data['hiding_rewards'] = agents_rewards[1]
data.drop('episode_rewards',axis=1,inplace=True)
# data.timestamps = data.timestamps * 1000000000

print(data.columns)

print(data['episode_winners'].value_counts())
print(data[data['episode_winners'] == 'SEEKER']['hiding_rewards'].describe())


"""
https://leetcode.com/problems/can-place-flowers/
"""

class Solution:
    """
    Be greedy: plant at the first occasion you can; update flowerbed if planted.

    Runtime: 185 ms, faster than 70.51% of Python3 online submissions for Can Place Flowers.
    Memory Usage: 14.4 MB, less than 75.14% of Python3 online submissions for Can Place Flowers.
    """
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        if n == 0:
            return True

        flowerbed = [0] + flowerbed + [0]

        for i in range(1, len(flowerbed) - 1):
            #check if able to plant
            if flowerbed[i] == flowerbed[i - 1] == flowerbed[i + 1] == 0:
                n -= 1
                flowerbed[i] = 1

                if n == 0:
                    return True

        return False

    """
    Inspired by https://leetcode.com/problems/can-place-flowers/discuss/184330/Python-easy-solution-beats-100 (some of the comments are funny)

    Basically, you need three 0s in a row to plant a flower.

    Runtime: 212 ms, faster than 52.12% of Python3 online submissions for Can Place Flowers.
    Memory Usage: 14.6 MB, less than 29.00% of Python3 online submissions for Can Place Flowers.
    """
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        flowerbed.append(0)
        count = 1
        for flower in flowerbed:
            if flower == 0:
                count += 1
            else:
                count = 0

            if count == 3:
                n -= 1
                count = 1

            if n == 0:
                return True

        return False


from django.urls import path
from . import views

urlpatterns = [
    path('', views.login_page, name='index'),
    path('inicio/', views.index, name='inicio'),
    path('registro/', views.register_page, name='register'),
    path('modificar_usuario/<int:id>', views.register_page, name='modificar_usuario'),
    path('listado_usuarios/', views.listado_usuarios, name='listado_usuarios'),
    path('borrar_usuario/<int:id>', views.borrar_usuario, name="borrar_usuario"),
    path('alta_grupo/', views.alta_grupo, name='alta_grupo'),
    path('modificar_grupo/<int:id>', views.alta_grupo, name='modificar_grupo'),
    path('listado_grupos/', views.listado_grupos, name='listado_grupos'),
    path('login/', views.login_page, name='login'),
    path('logout/', views.logout_user, name='logout'),
    path('alta_estadia_inicio/', views.alta_estadia_inicio,name='alta_estadia_inicio'),
    path('alta_estadia_final/<int:dia_inicio>/<int:mes_inicio>/<int:anio_inicio>/<int:dia_fin>/<int:mes_fin>/<int:anio_fin>/<int:cantidad_dias>/<int:habitacion>',views.alta_estadia_final, name='alta_estadia_final'),
    path('listado_estadias/', views.listado_estadias, name='listado_estadias'),
    path('borrar_estadia/<int:id>', views.borrar_estadia, name="borrar_estadia"),
    path('editar_estadia/<int:id>/<int:estado>', views.editar_estadia, name="editar_estadia"),
    path('editar_estadia_final/<int:id>/<int:habitacion>', views.editar_estadia_final, name="editar_estadia_final"),
    path('checkin-out_estadia/<int:id>/<str:accion>/<int:estado>', views.checkin_checkout_estadia, name="checkin-out_estadia"),
]


""" Nicely render a game with deck composition viewer and some graphs of
the game as it progresses."""

import itertools
import simplejson as json

import game
import goals
import parse_game
import sofia_predict

def _pretty_format_html(v):
    return '
' + pprint.pformat(v).replace(
        '\n', '
').replace(' ', '&nbsp')

win_predictor = sofia_predict.SofiaWinPredictor('data/logreg-peg.model')

def make_graph(label, div_name):
    return """

    %s

""" % (label, div_name)

def get_goals(game):
    glist = goals.check_goals(game)
    if len(glist)==0:
        goal_contents = None
    else:
        goal_contents = '
'
        for goal in glist:
            goal_name = goal['goal_name']
            player = goal['player']
            reason = goal['reason']
            reason = str.lower(reason[0:1]) + reason[1:]
            goal_contents += '
%s
%s %s
' % (goals.GetGoalImageFilename(goal_name), goal_name, goal_name, player, reason)
        goal_contents += '
'
    return "
goals	%s
"%goal_contents

def annotate_game(contents, game_id, debug=False):
    """ Decorate game contents with some JS that makes a score keeper
    and provides anchors per turn."""
    contents = contents.replace('—', '---')
    parsed_game = parse_game.parse_game(contents, dubious_check = False)
    states = []

    game_val = game.Game(parsed_game)
    win_prob_enabled = len(game_val.get_player_decks()) == 2
    if win_prob_enabled:
        predictions = win_predictor.predict_all_turns(game_val)

    for idx, game_state in enumerate(game_val.game_state_iterator()):
        encoded = game_state.encode_game_state()
        encoded['win_prob'] = predictions[idx] if win_prob_enabled else 0
        states.append(encoded)

    parsed_game['game_states'] = states

    ret = u''

    start_body = contents.find('') + len('')
    ret += contents[:start_body]
    ret += """

""" % (json.dumps(parsed_game, indent=2),
       open('static/card_list.js', 'r').read())
    contents = contents[start_body:]
    if debug > 2:
        ret += _pretty_format_html(parsed_game)
    if debug > 1:
        for turn in game_val.get_turns():
            ret += '%d %d %d %s %s
' % (
                turn.get_turn_no(),
                turn.get_player().TurnOrder(), turn.get_poss_no(),
                turn.turn_dict.get('poss', False),
                turn.get_player().name())

    import cStringIO as StringIO
    output_buf = StringIO.StringIO()
    if not parse_game.check_game_sanity(game_val, output_buf):
        ret += 'Parsing error, data mismatch, '
        ret += '''be a hero, find the
bug and tell rrenaud@gmail.com
''' % game_id
        ret += output_buf.getvalue().replace('\n', '
\n')

    cur_turn_ind = 0

    split_turn_chunks = parse_game.split_turns(contents)
    ret += split_turn_chunks[0]
    split_turn_chunks.pop(0)

    for idx, (turn_chunk, game_state) in enumerate(
        itertools.izip(split_turn_chunks, game_val.game_state_iterator())):
        split_chunk = turn_chunk.split('\n')

        turn_id = game_state.turn_label()
        show_turn_id = game_state.turn_label(for_anchor=True)
        ret += '

' % turn_id
        ret += '%s' % (
            show_turn_id, show_turn_id, split_chunk[0])

        if debug:
            ret += '
' + repr(game_val.get_turns()[cur_turn_ind]).replace(
                '\n', '
')
        cur_turn_ind += 1

        if idx != len(split_turn_chunks) - 1:
            ret += turn_chunk[turn_chunk.find('\n'):]
        else:
            before_end = turn_chunk.find('</html')
            ret += turn_chunk[turn_chunk.find('\n'): before_end]
            win_prob_graph = ''

            if win_prob_enabled:
                win_prob_graph = make_graph('win prob', 'win-prob-graph')
            ret += """

  %s
  %s
  %s
  %s

""" % (make_graph('score', 'score-graph'), make_graph('money', 'money-graph'),
       win_prob_graph, get_goals(game_val))
            ret += '
&nbsp
\n' * 10
            ret += ''
    return ret


"""
Ejercicio 10
-  Un programa que pida la nota de 15 alumnos y extraer por
pantalla cuantos han aprobado y cuantos han suspendido.
"""

"""
# bucle WHILE
contador = 0
aprobados = 0
suspensos = 0

numero_alumnos = int(input("¿Cuantos alumnos tienes?: "))

while contador <= numero_alumnos:
    nota = int(input("¿Que nota quieres ponerle al alumno?: "))

    if nota >= 5:
        aprobados += 1

    else:
        suspensos += 1

    contador += 1

print(f"Alumnos aprobados {aprobados}")
print(f"Alumnos suspensos {suspensos}")
"""

# bucle FOR

contador = 0
aprobados = 0
suspensos = 0

numeroalumno = 15

for numeroalumno in range(0, 15):
    nota = int(input(f"Que nota quieres darle al alumno: "))

    if nota >= 5:
        aprobados += 1

    else:
        suspensos += 1

    contador += 1

print(f"Alumnos aprobados: {aprobados}")
print(f"Alumnos suspensos: {suspensos}")


from django.contrib import admin
from django.urls import path,include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('site-admin-access/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path('accounts/', include('users.urls')),
    path("", include("company.urls")),
    path('', include('core.urls')),
    path('accounts/', include('wallet.urls')),
]

if settings.DEBUG :
    urlpatterns += static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)

handler404 = 'core.views.error_404_handler'
#handler500 = 'core.views.error_500_handler'
handler403 = 'core.views.error_403_handler'


#!/usr/bin/python
"""
# Ivan Domenzain.   Last edited: 2019-09-10
"""
#INPUTS:
ECM_path = '/Users/ivand/Documents/GitHub/ECM_Yeast'
R    = 0.008314472 #Universal constant of gases
Temp = 298.15      #25 celsius
#Load libraries
import os
from os import path
from math import exp
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from equilibrator_api import ComponentContribution, Reaction, ReactionMatcher

#Main Script
eq_api = ComponentContribution(pH=7.5, ionic_strength=0.1)
#Load model data file
os.chdir(ECM_path+'/Models')
data  = pd.read_table('KEGGmodelScaffold.txt')
os.chdir(ECM_path)
i=0
output     = '!!SBtab TableName=Parameter TableType=Quantity Document=S. cervisiae central carbon metabolism SBtabVersion=1.0'+'\n'
output     = output+ '!QuantityType'+'\t'+'!Reaction'+'\t'+'!Compound'+'\t'+'!Value'+'\t'+'!Unit'+'\t'+'!Reaction:Identifiers:kegg.reaction'+'\t'+'!Compound:Identifiers:kegg.compound'+'\t'+'!ID'+'\n'
unit       = 'dimensionless'
compound   = ' '
compoundID = ' '
type       = 'equilibrium constant'

for formula in data.ReactionFormula:
    rxn         = Reaction.parse_formula(formula)
    name        = str(data.ID[i])
    KEGGID      = str(data.KEGGIDs[i])
    reactionStr = name#+'_'+KEGGID
    parameterID = 'kEQ_'+name
    print(name)
    #Check if reaction is atomically balanced
    if not rxn.check_full_reaction_balancing():
        print('%s is not balanced' % name)
        #raw_input("Press the <ENTER> key to continue...")
        print(' ')
    i = i+1
    #Get standard Gibbs free energy for the rxn
    dG0_prime, dG0_uncertainty = eq_api.dG0_prime(rxn)
    if name == 'RIP1':
        dG0_prime = -38.46 #Edda Klipp's work
    if name == 'RIP1':
        dG0_prime = -38.46 #Edda Klipp's work
    KEQ = exp(-dG0_prime/(R*Temp))

    print("dG0' = %.1f uncertainty: %.1f kJ/mol" % (dG0_prime, dG0_uncertainty))
    print ("Keq  = %1f" % (KEQ))
    #Get reversibility index
    ln_RI  = rxn.reversibility_index()
    print('ln(Reversibility Index) = %.1f\n' % ln_RI)
    output = output+type+'\t'+reactionStr+'\t'+compound+'\t'+str(KEQ)+'\t'+unit+'\t'+ KEGGID+'\t'+compoundID+'\t'+parameterID+'\n'
#Write output:
os.chdir(ECM_path+'/results/parameters')
fid  = open('kEqTable.txt','w')
fid.write(output)
fid.close()
os.chdir(ECM_path)
################################################################################


#https://leetcode.com/problems/shortest-common-supersequence/
#Given two strings str1 and str2, return the shortest string that has both str1 and str2 as subsequences. If there are multiple valid strings, return any of them.
#A string s is a subsequence of string t if deleting some number of characters from t (possibly 0) results in the string s.

class Solution(object):
    def shortestCommonSupersequence(self, str1, str2):
        """
        :type str1: str
        :type str2: str
        :rtype: str
        """
        def get_lcs(str1, str2):
            m = len(str1)
            n = len(str2)
            dp = [[0] * (n+1) for _ in range(m+1)]
            for i in range(m):
                for j in range(n):
                    if str1[i] == str2[j]:
                        dp[i+1][j+1] = dp[i][j] + 1
                    else:
                        dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
            res = []
            i = m
            j = n
            while i > 0 and j > 0:
                if str1[i-1] == str2[j-1]:
                    res.append(str1[i-1])
                    i -= 1
                    j -= 1
                else:
                    if dp[i-1][j] > dp[i][j-1]:
                        i -= 1
                    else:
                        j -= 1
            return "".join(res[::-1])

        lcs = get_lcs(str1, str2)
        res = []
        i = j = k = 0
        while k < len(lcs):
            while i < len(str1) and str1[i] != lcs[k]:
                res.append(str1[i])
                i += 1
            while j < len(str2) and str2[j] != lcs[k]:
                res.append(str2[j])
                j += 1
            res.append(lcs[k])
            i += 1
            j += 1
            k += 1
        return "".join(res) + str1[i:] + str2[j:]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 13 19:02:56 2020

@author: AkashTyagi
"""

# Sudoku

board = [ [ 3, 1, 6, 5, 7, 8, 4, 9, 2 ],
         [ 5, 2, 9, 1, 3, 4, 7, 6, 8 ],
         [ 4, 8, 7, 6, 2, 9, 5, 3, 1 ],
         [ 2, 6, 3, 0, 1, 5, 9, 8, 7 ],
         [ 9, 7, 4, 8, 6, 0, 1, 2, 5 ],
         [ 8, 5, 1, 7, 9, 2, 6, 4, 3 ],
         [ 1, 3, 8, 0, 4, 7, 2, 0, 6 ],
         [ 6, 9, 2, 3, 5, 1, 8, 7, 4 ],
         [ 7, 4, 5, 0, 8, 6, 3, 1, 0 ] ]
def subcolumn(board,row,col):
    stack = []
    xr = row//3
    xy = col//3
    # Down
    for i in range(xr*3,xr*3+3):
        for j in range(xy*3,xy*3+3):
            if i>=0 and i<len(board[0]) and j>=0 and j<len(board[0]):
                stack.append(board[i][j])
    return stack

subcolumn(board,1,7)

def checkcolumn(board,row,col,target):
    for i in range(row-1,0):
        if board[i][col]==target:
            return False
    for i in range(row+1,len(board[0])):
        if board[i][col]==target:
            return False
    return True

def sudoku(board,row,col):
    for row in range(row,len(board)):
        for col in range(col,len(board[0])):
            if board[row][col]==0:
                for p in range(1,10):
                    if p not in board[row] and checkcolumn(board,row,col,p):
                        if p not in subcolumn(board,row,col):
                            board[row][col] = p
                            if sudoku(board,row,col):
                                return True
                            else:
                                board[row][col] = 0
                return False
            if col==len(board[0])-1:
                col = 0

    return True

sudoku(board,0,0)


"""
CLI for extracting the depth data.
"""

import os
import click
import ruamel.yaml as yaml
from tqdm.auto import tqdm
from copy import deepcopy
from moseq2_extract.util import command_with_config, read_yaml, recursive_find_unextracted_dirs
from moseq2_extract.helpers.wrappers import (get_roi_wrapper, extract_wrapper, flip_file_wrapper,
                                             generate_index_wrapper, aggregate_extract_results_wrapper,
                                             convert_raw_to_avi_wrapper, copy_slice_wrapper)
from moseq2_extract.helpers.extract import run_slurm_extract, run_local_extract

orig_init = click.core.Option.__init__

def new_init(self, *args, **kwargs):
    orig_init(self, *args, **kwargs)
    self.show_default = True

click.core.Option.__init__ = new_init

@click.group()
@click.version_option()
def cli():
    pass

def common_roi_options(function):
    """
    Decorator function for grouping shared ROI related parameters.

    Args:
    function: Function to add enclosed parameters to as click options.

    Returns:
    function: Updated function including shared parameters.
    """

    function = click.option('--bg-roi-dilate', default=(10, 10), type=(int, int),
                            help='Size of StructuringElement to dilate roi')(function)
    function = click.option('--bg-roi-shape', default='ellipse', type=str,
                            help='Shape to use to detect roi (ellipse or rect)')(function)
    function = click.option('--bg-roi-index', default=0, type=int,
                            help='Index of which detected ROI mask to use')(function)
    function = click.option('--bg-roi-weights', default=(1, .1, 1), type=(float, float, float),
                            help='ROI feature weighting (area, extent, dist to center)')(function)
    function = click.option('--camera-type', default='auto', type=click.Choice(["auto", "kinect", "azure", "realsense"]),
                            help='Camera type used for recording for auto-sets bg-roi-weights to precomputed values for different camera types. \
                             Possible types: ["kinect", "azure", "realsense"]')(function)
    function = click.option('--manual-set-depth-range', is_flag=True,
                            help='Flag to deactivate auto depth range setting.')(function)
    function = click.option('--bg-roi-depth-range', default=(650, 750), type=(float, float),
                            help='Range to search for floor of arena (in mm)')(function)
    function = click.option('--bg-roi-gradient-filter', default=False, type=bool,
                            help='Use graident filter to exclude walls for detected ROI')(function)
    function = click.option('--bg-roi-gradient-threshold', default=3000, type=float,
                            help='Gradient must be less than threshold to include points')(function)
    function = click.option('--bg-roi-gradient-kernel', default=7, type=int,
                            help='Kernel size for Sobel gradient filtering')(function)
    function = click.option('--bg-roi-fill-holes', default=True, type=bool, help='Fill holes in ROI')(function)
    function = click.option('--bg-sort-roi-by-position', default=False, type=bool,
                            help='Sort ROIs by position')(function)
    function = click.option('--bg-sort-roi-by-position-max-rois', default=2, type=int,
                            help='The number of maximum ROIs sorted by area')(function)
    function = click.option('--dilate-iterations', default=1, type=int,
                            help='Number of dilation iterations to increase bucket floor size.')(function)
    function = click.option('--bg-roi-erode', default=(1, 1), type=(int, int),
                            help='Size of cv2 Structure Element to erode roi.')(function)
    function = click.option('--erode-iterations', default=0, type=int,
                            help='Number of erosion iterations to decrease bucket floor size.')(function)
    function = click.option('--noise-tolerance', default=30, type=int,
                            help='Extent of noise to accept during RANSAC Plane ROI computation.')(function)
    function = click.option('--output-dir', default='proc', help='Output directory to save the results h5 file')(function)
    function = click.option('--use-plane-bground', is_flag=True,
                            help='Use a plane fit for the background. Useful when mice don\'t move much')(function)
    function = click.option('--recompute-bg', default=False, help='Overwrite previously computed background image')(
        function)
    function = click.option("--config-file", type=click.Path())(function)
    function = click.option('--progress-bar', '-p', is_flag=True, help='Show verbose progress bars.')(function)
    return function

def common_avi_options(function):
    """
    Decorator function for grouping shared video processing parameters.

    Args:
    function: Function to add enclosed parameters to as click options.

    Returns:
    function: Updated function including shared parameters.
    """

    function = click.option('-o', '--output-file', type=click.Path(), default=None, help='Path to output file')(function)
    function = click.option('-b', '--chunk-size', type=int, default=3000, help='Chunk size')(function)
    function = click.option('--fps', type=float, default=30, help='Video FPS')(function)
    function = click.option('--delete', is_flag=True, help='Delete raw file if encoding is sucessful')(function)
    function = click.option('-t', '--threads', type=int, default=8, help='Number of threads for encoding')(function)
    function = click.option('-m', '--mapping', type=str, default='DEPTH', help='Ffprobe stream selection variable. Default: DEPTH')(function)

    return function

def extract_options(function):
    """
    Decorator function for grouping shared extraction prameters.

    Args:
    function : Function to add enclosed parameters to as click options.

    Returns:
    function: Updated function including shared parameters.
    """

    function = click.option('--crop-size', '-c', default=(80, 80), type=(int, int), help='Width and height of cropped mouse image')(function)
    function = click.option('--num-frames', '-n', default=None, type=int, help='Number of frames to extract. Will extract full session if set to None.')(function)
    function = click.option('--min-height', default=10, type=int, help='Min mouse height threshold from floor (mm)')(function)
    function = click.option('--max-height', default=120, type=int, help='Max mouse height threshold from floor (mm)')(function)
    function = click.option('--detected-true-depth', default='auto', type=str, help='Option to override automatic depth estimation during extraction. \
This is only a debugging parameter, for cases where dilate_iterations > 1, otherwise has no effect. Either "auto" or an int value.')(function)
    function = click.option('--compute-raw-scalars', is_flag=True, help="Compute scalar values from raw cropped frames.")(function)
    function = click.option('--flip-classifier', default=None, help='path to the flip classifier used to properly orient the mouse (.pkl file)')(function)
    function = click.option('--flip-classifier-smoothing', default=51, type=int, help='Number of frames to smooth flip classifier probabilities')(function)
    function = click.option('--graduate-walls', default=False, type=bool, help="Graduates and dilates the background image to compensate for slanted bucket walls. \\_/")(function)
    function = click.option('--widen-radius', default=0, type=int, help="Number of pixels to increase/decrease radius by when graduating bucket walls.")(function)
    function = click.option('--use-cc', default=True, type=bool, help="Extract features using largest connected components.")(function)
    function = click.option('--use-tracking-model', default=False, type=bool, help='Use an expectation-maximization style model to aid mouse tracking. Useful for data with cables')(function)
    function = click.option('--tracking-model-ll-threshold', default=-100, type=float, help="Threshold on log-likelihood for pixels to use for update during tracking")(function)
    function = click.option('--tracking-model-mask-threshold', default=-16, type=float, help="Threshold on log-likelihood to include pixels for centroid and angle calculation")(function)
    function = click.option('--tracking-model-ll-clip', default=-100, type=float, help="Clip log-likelihoods below this value")(function)
    function = click.option('--tracking-model-segment', default=True, type=bool, help="Segment likelihood mask from tracking model")(function)
    function = click.option('--tracking-model-init', default='raw', type=str, help="Method for tracking model initialization")(function)
    function = click.option('--cable-filter-iters', default=0, type=int, help="Number of cable filter iterations")(function)
    function = click.option('--cable-filter-shape', default='rectangle', type=str, help="Cable filter shape (rectangle or ellipse)")(function)
    function = click.option('--cable-filter-size', default=(5, 5), type=(int, int), help="Cable filter size (in pixels)")(function)
    function = click.option('--tail-filter-iters', default=1, type=int, help="Number of tail filter iterations")(function)
    function = click.option('--tail-filter-size', default=(9, 9), type=(int, int), help='Tail filter size')(function)
    function = click.option('--tail-filter-shape', default='ellipse', type=str, help='Tail filter shape')(function)
    function = click.option('--spatial-filter-size', '-s', default=[3], type=int, help='Space prefilter kernel (median filter, must be odd)', multiple=True)(function)
    function = click.option('--temporal-filter-size', '-t', default=[0], type=int, help='Time prefilter kernel (median filter, must be odd)', multiple=True)(function)
    function = click.option('--chunk-overlap', default=0, type=int, help='Frames overlapped in each chunk. Useful for cable tracking')(function)
    function = click.option('--write-movie', default=True, type=bool, help='Write a results output movie including an extracted mouse')(function)
    function = click.option('--frame-dtype', default='uint8', type=click.Choice(['uint8', 'uint16']), help='Data type for processed frames')(function)
    function = click.option('--movie-dtype', default='<i2', help='Data type for raw frames read in for extraction')(function)
    function = click.option('--pixel-format', default='gray16le', type=str, help='Pixel format for reading in .avi and .mkv videos')(function)
    function = click.option('--centroid-hampel-span', default=0, type=int, help='Hampel filter span')(function)
    function = click.option('--centroid-hampel-sig', default=3, type=float, help='Hampel filter sig')(function)
    function = click.option('--angle-hampel-span', default=0, type=int, help='Angle filter span')(function)
    function = click.option('--angle-hampel-sig', default=3, type=float, help='Angle filter sig')(function)
    function = click.option('--model-smoothing-clips', default=(0, 0), type=(float, float), help='Model smoothing clips')(function)
    function = click.option('--frame-trim', default=(0, 0), type=(int, int), help='Frames to trim from beginning and end of data')(function)
    function = click.option('--compress', default=False, type=bool, help='Convert .dat to .avi after successful extraction')(function)
    function = click.option('--compress-chunk-size', type=int, default=3000, help='Chunk size for .avi compression')(function)
    function = click.option('--compress-threads', type=int, default=3, help='Number of threads for encoding')(function)
    function = click.option('--skip-completed', is_flag=True, help='Will skip the extraction if it is already completed.')(function)

    return function

@cli.command(name="find-roi", cls=command_with_config('config_file'), help="Finds the ROI (the arena) and background to subtract from frames when extracting.")
@click.argument('input-file', type=click.Path(exists=True))
@common_roi_options
def find_roi(input_file, output_dir, **config_data):

    get_roi_wrapper(input_file, config_data, output_dir)

@cli.command(name="extract", cls=command_with_config('config_file'),
             help="Processes raw input depth recordings to output a cropped and oriented"
             "video of the mouse and saves the output+metadata to h5 files in the given output directory.")
@click.argument('input-file', type=click.Path(exists=True, resolve_path=False))
@click.option('--cluster-type', type=click.Choice(['local', 'slurm']), default='local', help='Platform to train models on')
@common_roi_options
@common_avi_options
@extract_options
def extract(input_file, output_dir, num_frames, skip_completed, **config_data):

    extract_wrapper(input_file, output_dir, config_data, num_frames=num_frames, skip=skip_completed)

@cli.command(name='batch-extract', cls=command_with_config('config_file'), help='Batch processes '
             'all the raw depth recordings located in the input folder.')
@click.argument('input-folder', type=click.Path(exists=True, resolve_path=False))
@common_roi_options
@common_avi_options
@extract_options
@click.option('--extensions', default=['.dat'], type=str, help='File extension of raw data', multiple=True)
@click.option('--skip-checks', is_flag=True, help='Flag: skip checks for the existance of a metadata file')
@click.option("--extract-out-script", type=click.Path(), default='extract_out.sh', help="Name of bash script file to save extract commands.")
@click.option('--cluster-type', type=click.Choice(['local', 'slurm']), default='local', help='Platform to train models on')
@click.option('--prefix', type=str, default='', help='Batch command string to prefix model training command (slurm only).')
@click.option("--ncpus", "-c", type=int, default=1, help="Number of cores to use in extraction")
@click.option('--memory', type=str, default="5GB", help="RAM (slurm only)")
@click.option('--wall-time', type=str, default='3:00:00', help="Wall time (slurm only)")
@click.option('--partition', type=str, default='short', help="Partition name (slurm only)")
@click.option("--get-cmd", is_flag=True, default=True, help="Print scan command strings.")
@click.option("--run-cmd", is_flag=True, help="Run scan command strings.")
def batch_extract(input_folder, output_dir, skip_completed, num_frames, extensions,
                  skip_checks, **config_data):

    # check if there is a config file
    config_file = config_data.get('config_file')
    if not config_file:
        # Add message to tell the users to specify a config file
        print('Command not run. Please specified a config file using --config-file flag.')
        return

    # Add message to tell the users to specify a config file
    to_extract = []
    for ex in extensions:
        to_extract.extend(
            recursive_find_unextracted_dirs(input_folder, extension=ex,
                skip_checks=True if ex in ('.tgz', '.tar.gz') else skip_checks,
                 yaml_path=os.path.join(output_dir, 'results_00.yaml')))

    # Add message when all sessions are extracted
    if len(to_extract) == 0:
        print('No session to be extracted. If you want to re-extract the data, please add "--skip-checks"')
        return

    if config_data['cluster_type'] == 'local':
        # the session specific config doesn't get generated in session proc file
        # session specific config direct used in config_data dictionary in extraction from extract_command function
        run_local_extract(to_extract, config_file, skip_completed)
    else:
        # add paramters to config
        config_data['session_config_path'] = read_yaml(config_file).get('session_config_path', '') if config_file is not None else ''
        config_data['config_file'] = os.path.abspath(config_file)
        config_data['output_dir'] = output_dir
        config_data['skip_completed'] = skip_completed
        config_data['num_frames'] = num_frames
        config_data['extensions'] = extensions
        config_data['skip_checks'] = skip_checks
        # run slurm extract will generate a config.yaml in session proc file for slurm
        run_slurm_extract(input_folder, to_extract, config_data, skip_completed)

@cli.command(name="download-flip-file", help="Downloads Flip-correction model that helps with orienting the mouse during extraction.")
@click.argument('config-file', type=click.Path(exists=True, resolve_path=False), default='config.yaml')
@click.option('--output-dir', type=click.Path(),
              default=os.getcwd(), help="Output directory for downloaded flip flie")
def download_flip_file(config_file, output_dir):

    flip_file_wrapper(config_file, output_dir)

@cli.command(name="generate-config", help="Generates a configuration file (config.yaml) that holds editable options for extraction parameters.")
@click.option('--output-file', '-o', type=click.Path(), default='config.yaml')
@click.option('--camera-type', default='k2', type=str, help='specify the camera type (k2 or azure), default is k2')

def generate_config(output_file, camera_type):

    objs = extract.params
    params = {tmp.name: tmp.default for tmp in objs if not tmp.required}
    if camera_type=='azure':
        params['bg_roi_depth_range'] = [550, 650]
        params['spatial_filter_size'] = [5]
        params['tail_filter_size'] = [15, 15]
        params['crop_size'] = [120, 120]

    with open(output_file, 'w') as f:
        yaml.safe_dump(params, f)

    print('Successfully generated config file in base directory.')

@cli.command(name='generate-index', help='Generates an index file (moseq2-index.yaml) that contains all extracted session metadata.')
@click.option('--input-dir', '-i', type=click.Path(), default=os.getcwd(), help='Directory to find h5 files')
@click.option('--output-file', '-o', type=click.Path(), default=os.path.join(os.getcwd(), 'moseq2-index.yaml'), help="Location for storing index")
def generate_index(input_dir, output_file):

    output_file = generate_index_wrapper(input_dir, output_file)

    if output_file is not None:
        print(f'Index file: {output_file} was successfully generated.')

@cli.command(name='aggregate-results', help='Copies all extracted results (h5, yaml, mp4) files from all extracted sessions to a new directory for modeling and analysis')
@click.option('--input-dir', '-i', type=click.Path(), default=os.getcwd(), help='Directory to find h5 files')
@click.option('--format', '-f', type=str, default='{start_time}_{session_name}_{subject_name}', help='New file name formats from resepective metadata')
@click.option('--output-dir', '-o', type=click.Path(), default=os.path.join(os.getcwd(), 'aggregate_results/'), help="Location for storing all results together")
@click.option('--mouse-threshold', default=0, type=float, help='Threshold value for mean depth to include frames in aggregated results')
def aggregate_extract_results(input_dir, format, output_dir, mouse_threshold):

    aggregate_extract_results_wrapper(input_dir, format, output_dir, mouse_threshold)

@cli.command(name="convert-raw-to-avi", help='Loss less compresses a raw depth file (dat) into an avi file that is 8x smaller.')
@click.argument('input-file', type=click.Path(exists=True, resolve_path=False))
@common_avi_options
def convert_raw_to_avi(input_file, output_file, chunk_size, fps, delete, threads, mapping):

    convert_raw_to_avi_wrapper(input_file, output_file, chunk_size, fps, delete, threads, mapping)

@cli.command(name="copy-slice", help='Copies a segment of an input depth recording into a new video file.')
@click.argument('input-file', type=click.Path(exists=True, resolve_path=False))
@common_avi_options
@click.option('-c', '--copy-slice', type=(int, int), default=(0, 1000), help='Slice indices used for copy')
def copy_slice(input_file, output_file, copy_slice, chunk_size, fps, delete, threads, mapping):

    copy_slice_wrapper(input_file, output_file, copy_slice, chunk_size, fps, delete, threads, mapping)

if __name__ == '__main__':
    cli()


import json
from multiprocessing import get_logger

from pythontools.messaging.rabbitmq import Producer

class OutcomeProducer(Producer):
    def __init__(self, config):
        """
        Initialize outcome producer.
        """
        super().__init__(config)
        self.logger = get_logger()
        self.logger.info(f"initializing {OutcomeProducer.__name__} with {config}")

    def send_outcomes(self, odds):
        """
        This method serializes the outcomes and calls produce method,
        which is inherited from base Producer class,
        and passes the serialized odds as argument.
        """
        self.logger.info(f"serializing {odds} to json format")
        serialized_product = json.dumps(odds.__dict__, default=str)
        return self.produce(serialized_product)


import math
def func(x):
    return math.exp(float(-x))*((3.2)*math.sin(float(x)) - (0.5)*math.cos(float(x)))
    #return x * x * x - x * x + 2
def bisection(a,b):
    c = a
    while (b-a>0.001):
        c = (a+b)/2
        if func(c)==0:
            print("root is", c)
            break
        elif func(c)*func(a) < 0 :
            b = c
        elif func(c)*func(b) <0 :
            a = c
    return c
print(bisection(-10,20))


# N: 단어의 개수, K: 가르칠 글자

import collections

N, M = map(int, input().split())
words = list(input() for _ in range(N))

if M < 5:
    print(0)
    exit()
elif M == 26:
    print(N)
    exit()

result = 0
basic = 'antic'
learn = []

for i, word in enumerate(words):
    word = word[4:-4]
    learn.append([])

    for char in word:
        if char not in basic:
            learn[i].expand(char)

print(result)


import time, datetime
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor

def copy(param):
    return param

class Param:
    def __init__(self, v):
        self.v = v

values = [Param(i) for i in range(100000)]

def main():
    # マルチプロセス
    with ProcessPoolExecutor() as e:
        f = time.time()
        ret = e.submit(copy, values).result()
        print(f'ProcessPoolExecutor: {time.time() - f:.3f} sec')

    # マルチプロセス
    with ThreadPoolExecutor() as e:
        f = time.time()
        ret = e.submit(copy, values).result()
        print(f'ThreadPoolExecutor: {time.time() - f:.3f} sec')

if __name__ == '__main__':
    main()


from tkinter import *
from pygame import mixer
import tkinter.messagebox
from tkinter import filedialog
import os
from tkinter import ttk
from ttkthemes import themed_tk as tk

root = tk.ThemedTk()  # creates a window (short lived)
root.get_themes()
root.set_theme("plastik")
root.title("MyMix")
root.iconbitmap(r'favicon.ico')  # imports icon in .ico extension only

statusbar = ttk.Label(root, text="WELCOME TO MyMix", relief=SUNKEN, font='Courier 15 italic')
statusbar.pack(side=BOTTOM, fill=X)

leftframe = Frame(root)
leftframe.pack(side=LEFT, padx=30, pady=30)

rightframe = Frame(root)
rightframe.pack(pady=30)

topframe = Frame(rightframe)
topframe.pack()

middleframe = Frame(rightframe)
middleframe.pack(padx=10, pady=10)

bottomframe = Frame(rightframe)
bottomframe.pack()

mixer.init()  # initializing the mixer

def play_music():  # function to load and play music
    global paused
    if paused:
        mixer.music.unpause()  # unpauses the music when play button is clicked
        statusbar['text'] = "Music Resumed"
        paused = False
    else:
        try:
            stop_music()
            selected_song = playlist.curselection()  # selecting the current song to be played in the playlist
            selected_song = int(selected_song[0])  # returning the index of the song in the form of an integer
            play_it = playlist0[selected_song]  # using the hence found integer index of the song to play music
            mixer.music.load(play_it)
            mixer.music.play()
            statusbar["text"] = 'Now Playing' + ' ' + os.path.basename(play_it)
        except:  # error handling when flie not selected
            tkinter.messagebox.showerror('FILE NOT FOUND', 'Please select valid file')

playphoto = PhotoImage(file=r'play.png')  # add the play icon
playbtn = ttk.Button(middleframe, image=playphoto, command=play_music)
playbtn.grid(row=0, column=1, padx=10)

paused = False

def pause_music():  # function to pause music
    global paused
    paused = TRUE  # pauses the music
    mixer.music.pause()
    statusbar["text"] = 'Paused Playing'

pausephoto = PhotoImage(file=r'pause.png')  # add the stop icon
pausebtn = ttk.Button(middleframe, image=pausephoto, command=pause_music)
pausebtn.grid(row=0, column=3, padx=10)

def stop_music():  # function to stop music
    mixer.music.stop()
    statusbar["text"] = 'Stopped Playing'

stopphoto = PhotoImage(file=r'stop.png')  # add the stop icon
stopbtn = ttk.Button(middleframe, image=stopphoto, command=stop_music)
stopbtn.grid(row=0, column=2, padx=10)

def set_vol(val):  # function to set volume
    volume = float(val) / 100  # val takes values only between 1 and 0
    mixer.music.set_volume(volume)

scale = ttk.Scale(root, from_=0, to=100, orient=HORIZONTAL, command=set_vol)  # volume adjustment
scale.set(50)  # giving a default value to volume button
mixer.music.set_volume(0.5)
scale.pack(pady=10)

muted = False

def mute_music():
    global muted
    global last_volume
    if muted:
        mixer.music.set_volume(0.5)
        mutebtn.configure(image=volumephoto)
        scale.set(50)
        muted = False
    else:
        mixer.music.set_volume(0)
        mutebtn.configure(image=mutephoto)
        scale.set(0)
        muted = True

mutephoto = PhotoImage(file=r'mute.png')  # add the mute icon
volumephoto = PhotoImage(file=r'speaker.png')
mutebtn = ttk.Button(bottomframe, image=volumephoto, command=mute_music)
mutebtn.grid(row=0, column=2, padx=10)

menubar = Menu(root)  # create menubar
root.config(menu=menubar)

def browse_file():  # search for files
    global filename_path
    filename_path = filedialog.askopenfilename()
    add_to_playlist(filename_path)

submenu = Menu(menubar, tearoff=0)  # create the submenu
menubar.add_cascade(label="FILE", menu=submenu)
submenu.add_command(label="Search songs", command=browse_file)

def about_programmer():
    tkinter.messagebox.showinfo('About the programmer','Programmer Name:Farhaan Areeb\nReg.No.:21BCE1500\nCourse Code: BCSE103N')

submenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="HELP", menu=submenu)
submenu.add_command(label="about programmer", command=about_programmer)

submenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="EXIT", command=root.destroy)

playlist0 = []  # contains the full path and filename
playlist = Listbox(leftframe)  # contains only filename
playlist.pack()

def add_to_playlist(filename):  # create a playlist
    filename = os.path.basename(filename)
    index = 0
    playlist.insert(index, filename)
    playlist0.insert(index, filename_path)
    playlist.pack()
    index += 1

addbtn = ttk.Button(leftframe, text="+ADD", command=browse_file)  # create add and delete button for playlist
addbtn.pack(side=LEFT)

def del_song():  # delete songs fom playlist
    selected_song = playlist.curselection()
    selected_song = int(selected_song[0])
    playlist.delete(selected_song)
    playlist0.pop()  # removing items from the list, playlist0 to avoid pileup(good practice)

deletebtn = ttk.Button(leftframe, text="-DELETE", command=del_song)
deletebtn.pack(side=LEFT)

root.mainloop()  # looping the window hence created


# coding=utf-8
import collections
import fnmatch
import multiprocessing

try:
    import queue
except ImportError:
    import Queue as queue

import time

# 호가변경시 출력
def stk_echo(serieses, key, dat):
    print('Stk) %s, dat:%s' % (key[3:], dat))  # stk slice

def fut_echo(serieses, key, dat):
    futtype, code = key[:4], key[5:]
    print('%4s) %-8s [%s]' % (futtype, code, dat))  # fut slice

def opt_echo(serieses, key, dat):
    print('OPT:%s, dat:%s'% (key[3:], dat))  # opt slice

def tmp_echo(serieses, key, dat):
    print("('%s', '%s', )," % (key, dat))  # fut slice

def gen_eproc(observers=[]):
    e_proc = EventProcessor()
    e_proc.add_observer(['Stk*_A*'], stk_echo)
    e_proc.add_observer(['Fut*_*'], fut_echo)
    e_proc.add_observer(['#*'], tmp_echo)
    # e_proc.add_observer(['fut*_*'], fut_echo)
    # e_proc.add_observer(['opt*_*'], opt_echo)
    # e_proc.start()
    return e_proc

class EventProcessor(multiprocessing.Process):
    def __init__(self, deque_size=4096):
        super(EventProcessor, self).__init__()
        self.q_buf = multiprocessing.Queue()  #입력 버퍼
        self.o_buf = multiprocessing.Queue()  # 옵저버 버퍼
        self.observers = dict()  # 옵저버집합
        self.observer_list = []  # 옵저버 리스트
        self.serieses = dict()  # 시계열집합
        self.DQ_SIZE = deque_size

    def add_observer(self, key_patterns, callable):
        self.o_buf.put((key_patterns,callable))

    def push(self, key, data):
        ts = time.time()
        self.q_buf.put((ts, key, data))

    def run(self):
        while True:
            try:
                # 입력큐에서 하나 가져온다.
                itm = self.q_buf.get(timeout=1)
                ts = itm[0]  # push 메서드에서 넣은 순서
                key = itm[1]
                dat = itm[2]

                # 신규 옵저버 등록
                while self.o_buf.empty() == False:
                    self.observer_list.append(self.o_buf.get())

                # 키 확인, 없으면 추가
                if key not in self.serieses:
                    # 시계열에 해당 키 추가
                    self.serieses [key] = collections.deque(maxlen=self.DQ_SIZE)
                    self.observers[key] = []
                    # 모든 옵저버
                    for obv in self.observer_list:
                        patterns = obv[0]
                        callable = obv[1]
                        # 각 옵저버의 키패턴 unix-shell style로 패턴비교
                        for pat in patterns:
                            if fnmatch.fnmatch(key, pat):
                                self.observers[key].append(callable)

                # 덱에 원소 추가
                self.serieses[key].appendleft((ts, dat))

                # Notify
                for callback in self.observers[key]:
                    callback(self.serieses, key, dat)

            except queue.Empty:
                continue

if __name__ == "__main__":
    print('EventProcessor Test')


#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
Python action utility functions.
"""

import logging
import os
import shutil
import socket
import subprocess
import tempfile

import psutil
from django.utils.translation import ugettext as _

logger = logging.getLogger(__name__)

def is_systemd_running():
    """Return if we are running under systemd."""
    return os.path.exists('/run/systemd')

def service_is_running(servicename):
    """Return whether a service is currently running.

    Does not need to run as root.
    """
    try:
        if is_systemd_running():
            subprocess.run(['systemctl', 'status', servicename], check=True,
                           stdout=subprocess.DEVNULL)
        else:
            subprocess.run(['service', servicename, 'status'], check=True,
                           stdout=subprocess.DEVNULL)

        return True
    except subprocess.CalledProcessError:
        # If a service is not running we get a status code != 0 and
        # thus a CalledProcessError
        return False

def service_is_enabled(service_name, strict_check=False):
    """Check if service is enabled in systemd.

    In some cases, after disabling a service, systemd puts it into a state
    called 'enabled-runtime' and returns a positive response to 'is-enabled'
    query. Until we understand better, a conservative work around is to pass
    strict=True to services effected by this behavior.

    """
    try:
        process = subprocess.run(['systemctl', 'is-enabled', service_name],
                                 check=True, stdout=subprocess.PIPE,
                                 stderr=subprocess.DEVNULL)
        if not strict_check:
            return True

        return process.stdout.decode().strip() == 'enabled'
    except subprocess.CalledProcessError:
        return False

def service_enable(service_name):
    """Enable and start a service in systemd and sysvinit using update-rc.d."""
    subprocess.call(['systemctl', 'enable', service_name])
    service_start(service_name)

def service_disable(service_name):
    """Disable and stop service in systemd and sysvinit using update-rc.d."""
    try:
        service_stop(service_name)
    except subprocess.CalledProcessError:
        pass
    subprocess.call(['systemctl', 'disable', service_name])

def service_unmask(service_name):
    """Unmask a service"""
    subprocess.call(['systemctl', 'unmask', service_name])

def service_start(service_name):
    """Start a service with systemd or sysvinit."""
    service_action(service_name, 'start')

def service_stop(service_name):
    """Stop a service with systemd or sysvinit."""
    service_action(service_name, 'stop')

def service_restart(service_name):
    """Restart a service with systemd or sysvinit."""
    service_action(service_name, 'restart')

def service_try_restart(service_name):
    """Try to restart a service with systemd or sysvinit."""
    service_action(service_name, 'try-restart')

def service_reload(service_name):
    """Reload a service with systemd or sysvinit."""
    service_action(service_name, 'reload')

def service_action(service_name, action):
    """Preform the given action on the service_name."""
    if is_systemd_running():
        subprocess.run(['systemctl', action, service_name],
                       stdout=subprocess.DEVNULL)
    else:
        subprocess.run(['service', service_name, action],
                       stdout=subprocess.DEVNULL)

def webserver_is_enabled(name, kind='config'):
    """Return whether a config/module/site is enabled in Apache."""
    if not shutil.which('a2query'):
        return False

    option_map = {'config': '-c', 'site': '-s', 'module': '-m'}
    try:
        # Don't print anything on the terminal
        subprocess.check_output(['a2query', option_map[kind], name],
                                stderr=subprocess.STDOUT)
        return True
    except subprocess.CalledProcessError:
        return False

def webserver_enable(name, kind='config', apply_changes=True):
    """Enable a config/module/site in Apache.

    Restart/reload the webserver if apply_changes is True.  Return
    whether restart('restart'), reload('reload') or no action (None)
    is required.  If changes have been applied, then performed action
    is returned.
    """
    if webserver_is_enabled(name, kind) and kind == 'module':
        return

    command_map = {
        'config': 'a2enconf',
        'site': 'a2ensite',
        'module': 'a2enmod'
    }
    subprocess.check_output([command_map[kind], name])

    action_required = 'restart' if kind == 'module' else 'reload'

    if apply_changes:
        if action_required == 'restart':
            service_restart('apache2')
        else:
            service_reload('apache2')

    return action_required

def webserver_disable(name, kind='config', apply_changes=True):
    """Disable config/module/site in Apache.

    Restart/reload the webserver if apply_changes is True.  Return
    whether restart('restart'), reload('reload') or no action (None)
    is required.  If changes have been applied, then performed action
    is returned.
    """
    if not webserver_is_enabled(name, kind):
        return

    command_map = {
        'config': 'a2disconf',
        'site': 'a2dissite',
        'module': 'a2dismod'
    }
    subprocess.check_output([command_map[kind], name])

    action_required = 'restart' if kind == 'module' else 'reload'

    if apply_changes:
        if action_required == 'restart':
            service_restart('apache2')
        else:
            service_reload('apache2')

    return action_required

class WebserverChange(object):
    """Context to restart/reload Apache after configuration changes."""

    def __init__(self):
        """Initialize the context object state."""
        self.actions_required = set()

    def __enter__(self):
        """Return the context object so methods could be called on it."""
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """Restart or reload the webserver.

        Don't supress exceptions.  If an exception occurs
        restart/reload the webserver based on enable/disable
        operations done so far.
        """
        if 'restart' in self.actions_required:
            service_restart('apache2')
        elif 'reload' in self.actions_required:
            service_reload('apache2')

    def enable(self, name, kind='config'):
        """Enable a config/module/site in Apache.

        Don't apply the changes until the context is exited.
        """
        action_required = webserver_enable(name, kind, apply_changes=False)
        self.actions_required.add(action_required)

    def disable(self, name, kind='config'):
        """Disable a config/module/site in Apache.

        Don't apply the changes until the context is exited.
        """
        action_required = webserver_disable(name, kind, apply_changes=False)
        self.actions_required.add(action_required)

def diagnose_port_listening(port, kind='tcp', listen_address=None):
    """Run a diagnostic on whether a port is being listened on.

    Kind must be one of inet, inet4, inet6, tcp, tcp4, tcp6, udp,
    udp4, udp6, unix, all.  See psutil.net_connection() for more
    information.
    """
    result = _check_port(port, kind, listen_address)

    if listen_address:
        test = _('Listening on {kind} port {listen_address}:{port}') \
               .format(kind=kind, listen_address=listen_address, port=port)
    else:
        test = _('Listening on {kind} port {port}') \
               .format(kind=kind, port=port)

    return [test, 'passed' if result else 'failed']

def _check_port(port, kind='tcp', listen_address=None):
    """Return whether a port is being listened on."""
    run_kind = kind

    if kind == 'tcp4':
        run_kind = 'tcp'

    if kind == 'udp4':
        run_kind = 'udp'

    for connection in psutil.net_connections(run_kind):
        # TCP connections must have status='listen'
        if kind in ('tcp', 'tcp4', 'tcp6') and \
           connection.status != psutil.CONN_LISTEN:
            continue

        # UDP connections must have empty remote address
        if kind in ('udp', 'udp4', 'udp6') and \
           connection.raddr != ():
            continue

        # Port should match
        if connection.laddr[1] != port:
            continue

        # Listen address if requested should match
        if listen_address and connection.laddr[0] != listen_address:
            continue

        # Special additional checks only for IPv4
        if kind != 'tcp4' and kind != 'udp4':
            return True

        # Found socket is IPv4
        if connection.family == socket.AF_INET:
            return True

        # Full IPv6 address range includes mapped IPv4 address also
        if connection.laddr[0] == '::':
            return True

    return False

def diagnose_url(url, kind=None, env=None, check_certificate=True,
                 extra_options=None, wrapper=None, expected_output=None):
    """Run a diagnostic on whether a URL is accessible.

    Kind can be '4' for IPv4 or '6' for IPv6.
    """
    command = ['curl', '-f', '-w', '%{response_code}', url]

    if wrapper:
        command.insert(0, wrapper)

    if not check_certificate:
        command.append('-k')

    if extra_options:
        command.extend(extra_options)

    if kind:
        command.append({'4': '-4', '6': '-6'}[kind])

    try:
        process = subprocess.run(command, env=env, check=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        result = 'passed'
        if expected_output and expected_output not in process.stdout.decode():
            result = 'failed'
    except subprocess.CalledProcessError as exception:
        result = 'failed'
        # Authorization failed is a success
        if exception.stdout.decode().strip() in ('401', '405'):
            result = 'passed'
    except FileNotFoundError:
        result = 'error'

    if kind:
        return [
            _('Access URL {url} on tcp{kind}').format(url=url, kind=kind),
            result
        ]
    else:
        return [_('Access URL {url}').format(url=url), result]

def diagnose_url_on_all(url, **kwargs):
    """Run a diagnostic on whether a URL is accessible."""
    results = []
    for address in get_addresses():
        current_url = url.format(host=address['url_address'])
        results.append(
            diagnose_url(current_url, kind=address['kind'], **kwargs))

    return results

def diagnose_netcat(host, port, input='', negate=False):
    """Run a diagnostic using netcat."""
    try:
        process = subprocess.Popen(
            ['nc', host, str(port)], stdin=subprocess.PIPE,
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.communicate(input=input.encode())
        if process.returncode != 0:
            result = 'failed'
        else:
            result = 'passed'
    except Exception:
        result = 'failed'

    test = _('Connect to {host}:{port}')
    if negate:
        result = 'failed' if result == 'passed' else 'passed'
        test = _('Cannot connect to {host}:{port}')

    return [test.format(host=host, port=port), result]

def get_addresses():
    """Return a list of IP addreses and hostnames."""
    addresses = get_ip_addresses()

    hostname = get_hostname()
    addresses.append({
        'kind': '4',
        'address': 'localhost',
        'numeric': False,
        'url_address': 'localhost'
    })
    addresses.append({
        'kind': '6',
        'address': 'localhost',
        'numeric': False,
        'url_address': 'localhost'
    })
    addresses.append({
        'kind': '4',
        'address': hostname,
        'numeric': False,
        'url_address': hostname
    })

    # XXX: When a hostname is resolved to IPv6 address, it may likely
    # be link-local address.  Link local IPv6 addresses are valid only
    # for a given link and need to be scoped with interface name such
    # as '%eth0' to work.  Tools such as curl don't seem to handle
    # this correctly.
    # addresses.append({'kind': '6', 'address': hostname, 'numeric': False})

    return addresses

def get_ip_addresses():
    """Return a list of IP addresses assigned to the system."""
    addresses = []

    output = subprocess.check_output(['ip', '-o', 'addr'])
    for line in output.decode().splitlines():
        parts = line.split()
        address = {
            'kind': '4' if parts[2] == 'inet' else '6',
            'address': parts[3].split('/')[0],
            'url_address': parts[3].split('/')[0],
            'numeric': True,
            'scope': parts[5],
            'interface': parts[1]
        }

        if address['kind'] == '6' and address['numeric']:
            if address['scope'] != 'link':
                address['url_address'] = '[{0}]'.format(address['address'])
            else:
                address['url_address'] = '[{0}%{1}]'.format(
                    address['url_address'], address['interface'])

        addresses.append(address)

    return addresses

def get_hostname():
    """Return the current hostname."""
    return subprocess.check_output(['hostname']).decode().strip()

def dpkg_reconfigure(package, config):
    """Reconfigure package using debconf database override."""
    override_template = '''
Name: {package}/{key}
Template: {package}/{key}
Value: {value}
Owners: {package}
'''
    override_data = ''
    for key, value in config.items():
        override_data += override_template.format(package=package, key=key,
                                                  value=value)

    with tempfile.NamedTemporaryFile(mode='w', delete=False) as override_file:
        override_file.write(override_data)

    env = os.environ.copy()
    env['DEBCONF_DB_OVERRIDE'] = 'File{' + override_file.name + \
                                 ' readonly:true}'
    env['DEBIAN_FRONTEND'] = 'noninteractive'
    subprocess.run(['dpkg-reconfigure', package], env=env)

    try:
        os.remove(override_file.name)
    except OSError:
        pass

def is_disk_image():
    """Return whether the current machine is from a disk image.

    Two primary ways to install FreedomBox are:
    - Using FreedomBox image for various hardware platforms.
    - Installing packages on a Debian machine using apt.
    """
    return os.path.exists('/var/lib/freedombox/is-freedombox-disk-image')


import numpy as np

from ... import opcodes as OperandDef
from ...serialization.serializables import (
    FieldTypes,
    Int32Field,
    StringField,
    ListField,
    BoolField,
)
from ...core import ExecutableTuple
from ..array_utils import as_same_device, device
from ..core import TensorOrder
from ..datasource import tensor as astensor
from ..operands import TensorOperand, TensorShuffleProxy
from ..utils import validate_axis, validate_order
from .psrs import TensorPSRSOperandMixin

class TensorSort(TensorOperand, TensorPSRSOperandMixin):
    _op_type_ = OperandDef.SORT

    _axis = Int32Field("axis")
    _kind = StringField("kind")
    _parallel_kind = StringField("parallel_kind")
    _order = ListField("order", FieldTypes.string)
    _psrs_kinds = ListField("psrs_kinds", FieldTypes.string)
    _need_align = BoolField("need_align")
    _return_value = BoolField("return_value")
    _return_indices = BoolField("return_indices")

    def __init__(
        self,
        axis=None,
        kind=None,
        parallel_kind=None,
        order=None,
        psrs_kinds=None,
        need_align=None,
        return_value=None,
        return_indices=None,
        dtype=None,
        gpu=None,
        **kw,
    ):
        super().__init__(
            _axis=axis,
            _kind=kind,
            _parallel_kind=parallel_kind,
            _order=order,
            _psrs_kinds=psrs_kinds,
            _need_align=need_align,
            _return_value=return_value,
            _return_indices=return_indices,
            dtype=dtype,
            gpu=gpu,
            **kw,
        )

    @property
    def axis(self):
        return self._axis

    @property
    def kind(self):
        return self._kind

    @property
    def parallel_kind(self):
        return self._parallel_kind

    @property
    def order(self):
        return self._order

    @property
    def psrs_kinds(self):
        return self._psrs_kinds

    @property
    def need_align(self):
        return self._need_align

    @property
    def return_value(self):
        return self._return_value

    @property
    def return_indices(self):
        return self._return_indices

    @property
    def output_limit(self):
        return int(bool(self._return_value)) + int(bool(self._return_indices))

    def __call__(self, a):
        kws = []
        if self._return_value:
            kws.append(
                {"shape": a.shape, "order": a.order, "dtype": a.dtype, "type": "sorted"}
            )
        if self._return_indices:
            kws.append(
                {
                    "shape": a.shape,
                    "order": TensorOrder.C_ORDER,
                    "dtype": np.dtype(np.int64),
                    "type": "argsort",
                }
            )
        ret = self.new_tensors([a], kws=kws)
        if len(kws) == 1:
            return ret[0]
        return ExecutableTuple(ret)

    @classmethod
    def _tile_psrs(cls, op):
        """
        Refer to http://csweb.cs.wfu.edu/bigiron/LittleFE-PSRS/build/html/PSRSalgorithm.html
        to see explanation of parallel sorting by regular sampling
        """
        out_tensor = op.outputs[0]
        in_tensor, axis_chunk_shape, out_idxes, need_align = yield from cls.preprocess(
            op
        )
        axis_offsets = [0] + np.cumsum(in_tensor.nsplits[op.axis]).tolist()[:-1]
        return_value, return_indices = op.return_value, op.return_indices

        out_value_chunks, out_indices_chunks = [], []
        for out_idx in out_idxes:
            # stage 1: local sort and regular samples collected
            (
                sorted_chunks,
                indices_chunks,
                sampled_chunks,
            ) = cls.local_sort_and_regular_sample(
                op, in_tensor, axis_chunk_shape, axis_offsets, out_idx
            )

            # stage 2: gather and merge samples, choose and broadcast p-1 pivots
            concat_pivot_chunk = cls.concat_and_pivot(
                op, axis_chunk_shape, out_idx, sorted_chunks, sampled_chunks
            )

            # stage 3: Local data is partitioned
            partition_chunks = cls.partition_local_data(
                op, axis_chunk_shape, sorted_chunks, indices_chunks, concat_pivot_chunk
            )

            proxy_chunk = TensorShuffleProxy(dtype=partition_chunks[0].dtype).new_chunk(
                partition_chunks, shape=()
            )

            # stage 4: all *ith* classes are gathered and merged
            (
                partition_sort_chunks,
                partition_indices_chunks,
                sort_info_chunks,
            ) = cls.partition_merge_data(
                op, need_align, None, partition_chunks, proxy_chunk
            )

            if not need_align:
                if return_value:
                    out_value_chunks.extend(partition_sort_chunks)
                if return_indices:
                    out_indices_chunks.extend(partition_indices_chunks)
            else:
                (
                    align_reduce_value_chunks,
                    align_reduce_indices_chunks,
                ) = cls.align_partitions_data(
                    op,
                    out_idx,
                    in_tensor,
                    partition_sort_chunks,
                    partition_indices_chunks,
                    sort_info_chunks,
                )
                if return_value:
                    out_value_chunks.extend(align_reduce_value_chunks)
                if return_indices:
                    out_indices_chunks.extend(align_reduce_indices_chunks)

        new_op = op.copy()
        nsplits = list(in_tensor.nsplits)
        if not need_align:
            nsplits[op.axis] = (np.nan,) * axis_chunk_shape
        kws = []
        if return_value:
            kws.append(
                {
                    "shape": out_tensor.shape,
                    "order": out_tensor.order,
                    "chunks": out_value_chunks,
                    "nsplits": nsplits,
                    "dtype": out_tensor.dtype,
                }
            )
        if return_indices:
            kws.append(
                {
                    "shape": out_tensor.shape,
                    "order": TensorOrder.C_ORDER,
                    "chunks": out_indices_chunks,
                    "nsplits": nsplits,
                    "dtype": np.dtype(np.int64),
                }
            )
        return new_op.new_tensors(op.inputs, kws=kws)

    @classmethod
    def tile(cls, op):
        in_tensor = op.inputs[0]
        return_value, return_indices = op.return_value, op.return_indices

        if in_tensor.chunk_shape[op.axis] == 1:
            out_chunks, out_indices_chunks = [], []
            for chunk in in_tensor.chunks:
                chunk_op = op.copy().reset_key()
                kws = []
                if return_value:
                    kws.append(
                        {
                            "shape": chunk.shape,
                            "index": chunk.index,
                            "order": chunk.order,
                            "dtype": chunk.dtype,
                            "type": "sorted",
                        }
                    )
                if return_indices:
                    kws.append(
                        {
                            "shape": chunk.shape,
                            "index": chunk.index,
                            "order": TensorOrder.C_ORDER,
                            "dtype": np.dtype(np.int64),
                            "type": "argsort",
                        }
                    )
                chunks = chunk_op.new_chunks([chunk], kws=kws)
                if return_value:
                    out_chunks.append(chunks[0])
                if return_indices:
                    out_indices_chunks.append(chunks[-1])

            new_op = op.copy()
            kws = [out.params for out in op.outputs]
            if return_value:
                kws[0]["nsplits"] = in_tensor.nsplits
                kws[0]["chunks"] = out_chunks
            if return_indices:
                kws[-1]["nsplits"] = in_tensor.nsplits
                kws[-1]["chunks"] = out_indices_chunks
            return new_op.new_tensors([in_tensor], kws=kws)
        else:
            # use parallel sorting by regular sampling
            return (yield from cls._tile_psrs(op))

    @classmethod
    def execute(cls, ctx, op):
        (a,), device_id, xp = as_same_device(
            [ctx[inp.key] for inp in op.inputs], device=op.device, ret_extra=True
        )
        return_value, return_indices = op.return_value, op.return_indices

        with device(device_id):
            kw = {}
            if op.kind is not None:
                kw["kind"] = op.kind
            if op.order is not None:
                kw["order"] = op.order

            if return_indices:
                if not return_value:
                    ctx[op.outputs[0].key] = xp.argsort(a, axis=op.axis, **kw)
                else:
                    indices = ctx[op.outputs[1].key] = xp.argsort(a, axis=op.axis, **kw)
                    ctx[op.outputs[0].key] = xp.take_along_axis(a, indices, op.axis)
            else:
                ctx[op.outputs[0].key] = xp.sort(a, axis=op.axis, **kw)

_AVAILABLE_KINDS = {"QUICKSORT", "MERGESORT", "HEAPSORT", "STABLE"}

def _validate_sort_psrs_kinds(psrs_kinds):
    if psrs_kinds is not None:
        if isinstance(psrs_kinds, (list, tuple)):
            psrs_kinds = list(psrs_kinds)
            if len(psrs_kinds) != 3:
                raise ValueError("psrs_kinds should have 3 elements")
            for i, psrs_kind in enumerate(psrs_kinds):
                if psrs_kind is None:
                    if i < 2:
                        continue
                    else:
                        raise ValueError(
                            "3rd element of psrs_kinds should be specified"
                        )
                upper_psrs_kind = psrs_kind.upper()
                if upper_psrs_kind not in _AVAILABLE_KINDS:
                    raise ValueError(
                        f"{psrs_kind} is an unrecognized kind in psrs_kinds"
                    )
        else:
            raise TypeError("psrs_kinds should be list or tuple")
    else:
        psrs_kinds = ["quicksort", "mergesort", "mergesort"]
    return psrs_kinds

def _validate_sort_arguments(a, axis, kind, parallel_kind, psrs_kinds, order):
    a = astensor(a)
    if axis is None:
        a = a.flatten()
        axis = 0
    else:
        axis = validate_axis(a.ndim, axis)
    if kind is not None:
        raw_kind = kind
        kind = kind.upper()
        if kind not in _AVAILABLE_KINDS:
            # check kind
            raise ValueError(f"{raw_kind} is an unrecognized kind of sort")
    if parallel_kind is not None:
        raw_parallel_kind = parallel_kind
        parallel_kind = parallel_kind.upper()
        if parallel_kind not in {"PSRS"}:
            raise ValueError(
                f"{raw_parallel_kind} is an unrecognized kind of parallel sort"
            )

    order = validate_order(a.dtype, order)
    psrs_kinds = _validate_sort_psrs_kinds(psrs_kinds)
    return a, axis, kind, parallel_kind, psrs_kinds, order

def sort(
    a,
    axis=-1,
    kind=None,
    parallel_kind=None,
    psrs_kinds=None,
    order=None,
    return_index=False,
    **kw,
):
    r"""
    Return a sorted copy of a tensor.

    Parameters
    ----------
    a : array_like
        Tensor to be sorted.
    axis : int or None, optional
        Axis along which to sort. If None, the tensor is flattened before
        sorting. The default is -1, which sorts along the last axis.
    kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
        Sorting algorithm. The default is 'quicksort'. Note that both 'stable'
        and 'mergesort' use timsort or radix sort under the covers and, in general,
        the actual implementation will vary with data type. The 'mergesort' option
        is retained for backwards compatibility.
        Note that this argument would not take effect if `a` has more than
        1 chunk on the sorting axis.
    parallel_kind: {'PSRS'}, optional
        Parallel sorting algorithm, for the details, refer to:
        http://csweb.cs.wfu.edu/bigiron/LittleFE-PSRS/build/html/PSRSalgorithm.html
    psrs_kinds: list with 3 elements, optional
        Sorting algorithms during PSRS algorithm.
    order : str or list of str, optional
        When `a` is a tensor with fields defined, this argument specifies
        which fields to compare first, second, etc.  A single field can
        be specified as a string, and not all fields need be specified,
        but unspecified fields will still be used, in the order in which
        they come up in the dtype, to break ties.
    return_index: bool
        Return indices as well if True.

    Returns
    -------
    sorted_tensor : Tensor
        Tensor of the same type and shape as `a`.

    See Also
    --------
    Tensor.sort : Method to sort a tensor in-place.
    argsort : Indirect sort.
    lexsort : Indirect stable sort on multiple keys.
    searchsorted : Find elements in a sorted tensor.
    partition : Partial sort.

    Notes
    -----
    The various sorting algorithms are characterized by their average speed,
    worst case performance, work space size, and whether they are stable. A
    stable sort keeps items with the same key in the same relative
    order. The four algorithms implemented in NumPy have the following
    properties:

    =========== ======= ============= ============ ========
       kind      speed   worst case    work space   stable
    =========== ======= ============= ============ ========
    'quicksort'    1     O(n^2)            0          no
    'heapsort'     3     O(n*log(n))       0          no
    'mergesort'    2     O(n*log(n))      ~n/2        yes
    'timsort'      2     O(n*log(n))      ~n/2        yes
    =========== ======= ============= ============ ========

    .. note:: The datatype determines which of 'mergesort' or 'timsort'
       is actually used, even if 'mergesort' is specified. User selection
       at a finer scale is not currently available.

    All the sort algorithms make temporary copies of the data when
    sorting along any but the last axis.  Consequently, sorting along
    the last axis is faster and uses less space than sorting along
    any other axis.

    The sort order for complex numbers is lexicographic. If both the real
    and imaginary parts are non-nan then the order is determined by the
    real parts except when they are equal, in which case the order is
    determined by the imaginary parts.

    quicksort has been changed to an introsort which will switch
    heapsort when it does not make enough progress. This makes its
    worst case O(n*log(n)).

    'stable' automatically choses the best stable sorting algorithm
    for the data type being sorted. It, along with 'mergesort' is
    currently mapped to timsort or radix sort depending on the
    data type. API forward compatibility currently limits the
    ability to select the implementation and it is hardwired for the different
    data types.

    Timsort is added for better performance on already or nearly
    sorted data. On random data timsort is almost identical to
    mergesort. It is now used for stable sort while quicksort is still the
    default sort if none is chosen. For details of timsort, refer to
    `CPython listsort.txt <https://github.com/python/cpython/blob/3.7/Objects/listsort.txt>`_.
    'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an
    O(n) sort instead of O(n log n).

    Examples
    --------
    >>> import mars.tensor as mt
    >>> a = mt.array([[1,4],[3,1]])
    >>> mt.sort(a).execute()                # sort along the last axis
    array([[1, 4],
           [1, 3]])
    >>> mt.sort(a, axis=None).execute()     # sort the flattened tensor
    array([1, 1, 3, 4])
    >>> mt.sort(a, axis=0).execute()        # sort along the first axis
    array([[1, 1],
           [3, 4]])

    Use the `order` keyword to specify a field to use when sorting a
    structured array:

    >>> dtype = [('name', 'S10'), ('height', float), ('age', int)]
    >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38),
    ...           ('Galahad', 1.7, 38)]
    >>> a = mt.array(values, dtype=dtype)       # create a structured tensor
    >>> mt.sort(a, order='height').execute()                # doctest: +SKIP
    array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
           ('Lancelot', 1.8999999999999999, 38)],
          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])

    Sort by age, then height if ages are equal:

    >>> mt.sort(a, order=['age', 'height']).execute()       # doctest: +SKIP
    array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38),
           ('Arthur', 1.8, 41)],
          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
    """
    need_align = kw.pop("need_align", None)
    if len(kw) > 0:
        raise TypeError(f"sort() got an unexpected keyword argument '{next(iter(kw))}'")
    a, axis, kind, parallel_kind, psrs_kinds, order = _validate_sort_arguments(
        a, axis, kind, parallel_kind, psrs_kinds, order
    )
    op = TensorSort(
        axis=axis,
        kind=kind,
        parallel_kind=parallel_kind,
        order=order,
        psrs_kinds=psrs_kinds,
        need_align=need_align,
        return_value=True,
        return_indices=return_index,
        dtype=a.dtype,
        gpu=a.op.gpu,
    )
    return op(a)


from flask import Flask, request, jsonify
import modules.judge_spacy  as jus
import modules.mysql_conn as mysql
import modules.get_rank as rank

app = Flask(__name__)

# 日本語を使えるように
app.config['JSON_AS_ASCII'] = False

@app.route('/pyapi/', methods=['POST'])
def post_json():
    reqJson = request.get_json()["title"]
    resMes, source= jus.cos_distance(reqJson)
    ref = {
        "title":resMes[0],
        "source":source[0],
        "title1":resMes[1],
        "source1":source[1],
        "title2":resMes[2],
        "source2":source[2],
        "title3":resMes[3],
        "source3":source[3],
    }
    return jsonify(ref)

@app.route('/pyapi/calendar/update/', methods=['POST'])
def cal_update():
    reqJson = request.get_json()
    mysql.mysqlUpdate(reqJson)
    print(reqJson)
    ref = {
        "res":"ok",
    }
    return jsonify(ref)

@app.route('/pyapi/calendar/push/', methods=['POST'])
def cal_push():
    reqJson = request.get_json()
    mysql.mysqlPush(reqJson)
    print(reqJson)
    ref = {
        "res":"ok",
    }
    return jsonify(ref)

@app.route('/pyapi/calendar/delete/', methods=['POST'])
def cal_delete():
    reqJson = request.get_json()
    mysql.mysqlDel(reqJson)
    print(reqJson)
    ref = {
        "res":"ok",
    }
    return jsonify(ref)

@app.route('/pyapi/calendar/get/',methods=['POST'])
def get_json():
    reqJson = request.get_json()
    print(reqJson)
    return jsonify(mysql.mysqlList(reqJson))

@app.route('/pyapi/rank_table/get/',methods=['GET'])
def get_rank():
    ranking = rank.get_rank()
    ref = {
        "res1":ranking[0],
        "res2":ranking[1],
        "res3":ranking[2],
        "res4":ranking[3],
        "res5":ranking[4],
    }
    return jsonify(ref)
if __name__ == '__main__':
    app.run()


n=5
i=1
while i<=n:
    j=1
    while j<=i:
        print(j,end=" ")
        j+=1
    print()
    i+=1

n=153
orig=n
l=len(str(n))
sum=0
while i>0:
    sum+=(n%10)**l
    n=n//10
if n==orig:
    print("AMSTRONG NUMBER")
else:
    print("NOT AMSTRONG NUMBER ")

def fact(n):
    if n==0:
        return 1
    return n*fact(n-1)
n=6
print(fact(n))


from .views import InitiatePayment,VerifyPayment,VerifyAccount
from django.urls import path
app_name = 'mgt'

urlpatterns = [
    path('',InitiatePayment.as_view(), name="initiate-payment"),
    path('<str:ref>/', VerifyPayment.as_view(), name="verify-payment"),
    path('<int:pk>/verify_account/', VerifyAccount.as_view(), name="verify-account"),

]


class SelfLearning:
    # constructor, means putting all default values in it
    # executes at the first while calling the class
    def __init__(self):
        self.name = "swetha"
        self.name1 = "swetha test"

    def weekday(self):

        return self.name

if __name__ == '__main__':
    # SelfLearning() is a class
    # sf is an object created from the class
    sf = SelfLearning()
    print(sf.name1)
    print(sf.weekday())


# Based on https://medium.com/analytics-vidhya/pytorch-for-deep-learning-binary-classification-logistic-regression-382abd97fb43
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

def get_data(csv_file, training_size_frac=0.75):
    df = pd.read_csv(csv_file)
    X = np.array([df[label] for label in df.columns[1:(len(df.columns)-2)]])
    X = X.transpose()
    Y = np.array(df[df.columns[-1]])
    Y = np.array([1 if _y==0 else 0 for _y in Y])
    print(Y)

    training_set_len = int(training_size_frac*X.shape[0])

    X_train = X[:training_set_len,:]
    Y_train = Y[:training_set_len]

    X_eval = X[training_set_len:,:]
    Y_eval = Y[training_set_len:]
    X_train, Y_train, X_eval, Y_eval = map(torch.tensor, (X_train, Y_train, X_eval, Y_eval))
    #return X_train.float(), Y_train.long(), X_eval.float(), Y_eval.long()
    return X_train.float(), Y_train.float(), X_eval.float(), Y_eval.float()

class dataset(Dataset):
    def __init__(self,x,y):
        self.x = torch.tensor(x,dtype=torch.float32)
        self.y = torch.tensor(y,dtype=torch.float32)
        self.length = self.x.shape[0]

    def __getitem__(self,idx):
        return self.x[idx],self.y[idx]

    def __len__(self):
        return self.length

class Net(nn.Module):
    def __init__(self,input_shape):
        super(Net,self).__init__()
        self.fc1 = nn.Linear(input_shape,400)
        self.fc2 = nn.Linear(400,200)
        self.fc3 = nn.Linear(200,1)

        self.dropout = nn.Dropout(p=0.3)

    def forward(self,x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.dropout(x)
        x = torch.sigmoid(self.fc3(x))
        return x

if __name__ == '__main__':
    X_train, y_train, X_test, y_test = get_data('Descriptors1545Label.csv')

    LEARNING_RATE = 0.01
    BATCH_SIZE = 64
    L2_REGULARIZATION = 0.025
    EPOCHS = 1000

    x = X_train
    y = y_train

    sc = StandardScaler()
    x = sc.fit_transform(x)
    X_test = sc.fit_transform(X_test)

    trainset = dataset(x,y)#DataLoader
    trainloader = DataLoader(trainset,batch_size=BATCH_SIZE,shuffle=False)

    model = Net(input_shape=x.shape[1])
    optimizer = torch.optim.SGD(model.parameters(),lr=LEARNING_RATE, weight_decay=L2_REGULARIZATION)
    loss_fn = nn.BCELoss()

    #forward loop
    losses = []
    accur = []
    print(x.shape)
    for i in range(EPOCHS):
        for j,(x_train,y_train) in enumerate(trainloader):

            #calculate output
            output = model(x_train)

            #calculate loss
            loss = loss_fn(output,y_train.reshape(-1,1))

            #accuracy
            predicted = model(torch.tensor(X_test, dtype=torch.float32))
            acc = (predicted.reshape(-1).detach().round() == y_test).float().mean()

            #backprop
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        losses.append(loss)
        accur.append(acc)
        if i%50 == 0:
            print("epoch {}\tloss : {}\t accuracy : {}".format(i,loss,acc))

    #plt.plot(accur, label = 'Accuracy over test set')
    plt.plot(accur, label = 'Loss')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy over the test set')
    plt.ylim(.5, .8)
    #plt.legend(loc='center right')
    plt.savefig('TestCurve', dpi=300)
    plt.show()


# -*- coding: utf-8 -*-
import unittest

import numpy

import chainer
from chainer import cuda
from chainer import functions
from chainer import gradient_check
from chainer import testing
from chainer.testing import attr

from roi_align_2d import ROIAlign2D, roi_align_2d

class TestROIAlign2D(unittest.TestCase):
    def setUp(self):
        N = 3
        n_channels = 256
        self.x = numpy.arange(
            N * n_channels * 12 * 8, dtype=numpy.float32).reshape(
                (N, n_channels, 12, 8))
        numpy.random.shuffle(self.x)
        self.x = 2 * self.x / self.x.size - 1
        self.x = self.x.astype(numpy.float32)
        self.rois = numpy.array(
            [[0, 1, 1, 6, 6], [2, 6, 2, 7, 11], [1, 3, 1, 5, 10],
             [0, 3, 3, 3, 3]],
            dtype=numpy.float32)
        self.rois = numpy.tile(self.rois, (15, 1))
        n_rois = self.rois.shape[0]
        self.outh, self.outw = 5, 7
        self.spatial_scale = 0.6
        self.gy = numpy.random.uniform(
            -1, 1, (n_rois, n_channels, self.outh, self.outw)).astype(
                numpy.float32)
        self.check_backward_options = {'atol': 1e-3, 'rtol': 1e-2}

    def check_forward(self, x_data, roi_data):
        x = chainer.Variable(x_data)
        rois = chainer.Variable(roi_data)
        y = roi_align_2d(
            x,
            rois,
            outh=self.outh,
            outw=self.outw,
            spatial_scale=self.spatial_scale)
        self.assertEqual(y.data.dtype, numpy.float32)
        y_data = cuda.to_cpu(y.data)

        self.assertEqual(self.gy.shape, y_data.shape)

    def test_forward_cpu(self):
        self.check_forward(self.x, self.rois)

    @attr.gpu
    def test_forward_gpu(self):
        self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.rois))

    @attr.gpu
    def test_forward_cpu_gpu_equal(self):
        # cpu
        x_cpu = chainer.Variable(self.x)
        rois_cpu = chainer.Variable(self.rois)
        y_cpu = roi_align_2d(
            x_cpu,
            rois_cpu,
            outh=self.outh,
            outw=self.outw,
            spatial_scale=self.spatial_scale)

        # gpu
        x_gpu = chainer.Variable(cuda.to_gpu(self.x))
        rois_gpu = chainer.Variable(cuda.to_gpu(self.rois))
        y_gpu = roi_align_2d(
            x_gpu,
            rois_gpu,
            outh=self.outh,
            outw=self.outw,
            spatial_scale=self.spatial_scale)
        testing.assert_allclose(y_cpu.data, cuda.to_cpu(y_gpu.data))

    def check_backward(self, x_data, roi_data, y_grad):
        gradient_check.check_backward(
            ROIAlign2D(
                outh=self.outh,
                outw=self.outw,
                spatial_scale=self.spatial_scale), (x_data, roi_data),
            y_grad,
            no_grads=[False, True],
            **self.check_backward_options)

    def test_backward_cpu(self):
        self.check_backward(self.x, self.rois, self.gy)

    @attr.gpu
    def test_backward_gpu(self):
        self.check_backward(
            cuda.to_gpu(self.x), cuda.to_gpu(self.rois), cuda.to_gpu(self.gy))

    def test_caffe2_equal(self):
        try:
            from caffe2.python import core, workspace
        except:
            assert False

        op = core.CreateOperator(
            "RoIAlign", ["x", "rois"], ["y"],
            order="NCHW",
            pooled_h=self.outh,
            pooled_w=self.outw,
            spatial_scale=self.spatial_scale,
            sampling_ratio=1)
        workspace.ResetWorkspace()
        workspace.FeedBlob("x", self.x)
        workspace.FeedBlob("rois", self.rois)
        workspace.RunOperatorOnce(op)
        y_caffe = workspace.FetchBlob("y")

        x = chainer.Variable(self.x)
        rois = chainer.Variable(self.rois)
        y = roi_align_2d(
            x,
            rois,
            outh=self.outh,
            outw=self.outw,
            spatial_scale=self.spatial_scale)
        self.assertEqual(y.data.dtype, numpy.float32)
        y_data = cuda.to_cpu(y.data)
        gradient_check.assert_allclose(y_caffe, y_data)

    def test_forward_cpu_1_2_equal(self):
        # cpu
        x = chainer.Variable(self.x)
        rois = chainer.Variable(self.rois)
        import time
        start = time.time()
        y1 = roi_align_2d(
            x,
            rois,
            outh=self.outh,
            outw=self.outw,
            spatial_scale=self.spatial_scale)
        elapsed_time = time.time() - start
        print("elapsed_time:{0}".format(elapsed_time) + "[sec]")

        start = time.time()
        y2, = ROIAlign2D(self.outh, self.outw,
                         self.spatial_scale).forward_cpu2((self.x, self.rois))
        elapsed_time = time.time() - start
        print("elapsed_time:{0}".format(elapsed_time) + "[sec]")

        testing.assert_allclose(y1.data, y2.data)

testing.run_module(__name__, __file__)


from genanki import Model

DEFAULT_INPUT_FRONT = "{{Front}}" "
" "{{type:Input}}"
DEFAULT_INPUT_BACK = "{{FrontSide}}" '
' "{{Back}}"

def input_model(id, name, css, qfmt, afmt):
        if qfmt is None:
                qfmt = DEFAULT_INPUT_FRONT
        if afmt is None:
                afmt = DEFAULT_INPUT_BACK
        return Model(id, name,
                fields=[
                {"name": "Front"},
                {"name": "Back"},
                {"name": "Input"},
                {"name": "MyMedia"},
                ],
                templates=[
                {
                        "name": name,
                        "qfmt": qfmt,
                        "afmt": afmt,
                }
                ],
                css=css,
        )