import fitz  # PyMuPDF
import re
import json
from unidecode import unidecode

#Codigo responsável pela leitura de um arquivo com os dados de orientadores e suas áreas
#Do PDF responsável pelo enic daquele ano e cria um arquivo de dados contendo os resumos de cada orientador junto as suas áreas e subáreas

# A pagina inicial deve ser a pagina do pdf que começam os resumos -1
quantidadeResumos =  103 # Variável que irá ser responsável por percorrer todas as páginas que possuem resumo
resumos: list = []  # Lista onde ficará armazenado os dicionários sobre cada resumo

nome_pdf = "../DadosEnic/enic17.pdf"
resumo_nome = "../resumoOrientadores/resumoOrientadores17.json"
caminho_projetos = "../CriadorDadosModelo/projetos2017.json"
planos_nao_achados = "../resumoOrientadores/nao_achados17.txt"

# Função responsável por retirar o email do nome
# No Enic 17 foi necessário essa mudança, pois o algoritmo atual armazenava o email junto a string do nome
def retira_email(nome_e_email):

    frase: str= nome_e_email

    palavras: list = frase.split()

    palavra_final: str = ""

    for palavra in palavras:
        palavra_final += (palavra if '@' not in palavra else '') + ' '

    return palavra_final

#Abre o arquivo json de projetos
def abre_projetos(projetos_arquivo):

    projetos = list()
    with open(projetos_arquivo) as file:
        projetos = json.load(file)
    file.close()
    return projetos

def clean_text(text):
    # Substituir múltiplos espaços por um único espaço
    text = re.sub(r'\s+', ' ', text)

    # Remover caracteres especiais e não-ASCII
    text = re.sub(r'[^\x00-\x7F]+', ' ', text)

    # Remover quebras de linha e tabulações
    text = text.replace('\n', ' ').replace('\t', ' ')

    # Remover espaços em branco extras no início e no final
    text = text.strip()

    return text

#Função responsável por receber uma string e retornar apenas em formato asc
def asc_string(string):

    text = ''
    for letter in string:
        if ord(letter) <= 122 and ord(letter) >= 97:
            text += letter

    return text

#Estamos abrindo um arquivo para leitura binária, nomeado de resumo
with open(nome_pdf, 'rb') as resumo_pdf:
    # Fazendo a leitura do documento e armazenando em um objeto chamado resumoRead
    resumoRead = fitz.open(stream=resumo_pdf.read(), filetype="pdf")

    # Pega-se o número de páginas e armazenar em um objeto chamado resumoPages
    resumoPages = resumoRead.page_count

    # Nome do resumo a ser criado
    projetos = abre_projetos(caminho_projetos)

    # Cria lista de projetos que foram achados ou não, inicaliza todas as variáveis como False
    achados = 0
    projetos_contidos = list()

    for i in range(len(projetos)):
        projetos_contidos.append(False)

    enic_resumos = list()
    enic_resumos_sem_espaco = list()
    while quantidadeResumos < resumoPages:
        print(quantidadeResumos)

        # Vamos ler a página dada como parâmetro e armazenar em um objeto chamado page

        page = resumoRead.load_page(quantidadeResumos)

        # Extraimos o texto daquele objeto extraido na linha anterior

        pageConteudo = page.get_text("text")
        pageConteudo = re.sub('\n', '', pageConteudo)

        # Lista para retirar os resumos
        enic_resumos.append(pageConteudo)

        # Tratamento para localizar o plano
        # Pois algumas instancias do ENIC bugava com letras não ascii
        page_sem_espaco = (re.sub(' ', '', pageConteudo)).lower()
        page_sem_espaco = asc_string(page_sem_espaco)
        enic_resumos_sem_espaco.append(page_sem_espaco)

        quantidadeResumos += 1

    print("Lido todo o PDF")

    for i, projeto in enumerate(projetos):
        # Realiza o tratamento do texto para o nome do plano
        projeto_plano = re.sub('\n', '', projeto['Plano:'])
        projeto_plano = re.sub(' ', '', projeto_plano)
        text_treated = asc_string(projeto_plano.lower())

        projeto_achado = False
        indice_projeto_achado = 0

        for j, page in enumerate(enic_resumos):

            if text_treated in enic_resumos_sem_espaco[j]:
                projeto_achado = True
                achados += 1
                projetos_contidos[i] = True
                indice_projeto_achado = i

            if(projeto_achado) :
                posicaoResumoInicial: int = 0
                #Vamos pegar a posição do início do resumo daquela página
                if page.find("Resumo:") != - 1:
                    posicaoResumoInicial = page.find("Resumo:")
                else:
                    posicaoResumoInicial = page.find("RESUMO") - 1

                #Posicao Final do resumo é quando achamos a string "Palavras-Chave:"

                posicaoResumoFinal: int = 0
                if pageConteudo.find("Palavras-Chave:") != -1:
                    posicaoResumoFinal = page.find("Palavras-Chave:")
                elif pageConteudo.find("Palav ras-Chave") != -1:
                    posicaoResumoFinal = page.find("Palav ras-Chave")
                elif pageConteudo.find("Palavras Chave") != -1:
                    posicaoResumoFinal = page.find("Palavras Chave")
                else:
                    posicaoResumoFinal = page.find("Palavras -Chave")

                #Recebe-se o dicionário
                resumo_dict = projetos[indice_projeto_achado]
                resumo_dict['texto:'] = page[posicaoResumoInicial + 8:posicaoResumoFinal].lstrip()
                resumo_dict['texto:'] = resumo_dict["texto:"].rstrip()

                incluso = False
                for resumo in resumos:
                    if resumo["id"] == resumo_dict["id"]:
                        incluso = True

                if not incluso:
                    #Adiciona-se o dicionario na lista de resumos
                    resumos.append(resumo_dict.copy())
                break

    # Responsável por criar o json do resumo dos orientadores
    with open(resumo_nome, 'w') as resumo_js:
        json.dump(resumos, resumo_js, indent = 4, ensure_ascii=False)
    resumo_js.close()

    # Cria um arquivo txt responsável por dizer quais foram os planos não achados
    arq_nao_achados = open(planos_nao_achados, "w+")

    for i in range(len(projetos_contidos)):
        if projetos_contidos[i] == False:
            arq_nao_achados.write(str(i) + ' ')
            arq_nao_achados.write('\n')

    arq_nao_achados.close()

    print(f'Foram achados {len(resumos)} resumos')

    resumo_pdf.close()


import snafu

# --- Constants ---
INPUT_FILE = "../input/input.txt"

# --- Read and parse the input file ---
with open(INPUT_FILE, "r") as file:
    text = file.read()

total = sum(map(lambda line: snafu.from_snafu(line), text.strip().split("\n")))
snafu = snafu.to_snafu(total)
print(f"SNAFU number to supply to Bob's console: {snafu}")


from copy import deepcopy
import typing as tp

from . import operations as ops
from .external_sort import ExternalSort

class Graph:
    """Computational graph implementation"""

    def __init__(self) -> None:
        self.__operations: list["ops.Operation"] = []
        self.__graphs_for_join: list["Graph"] = []

    @staticmethod
    def graph_from_iter(name: str) -> "Graph":
        """Construct new graph which reads data from row iterator (in form of sequence of Rows
        from "kwargs" passed to "run" method) into graph data-flow
        Use ops.ReadIterFactory
        :param name: name of kwarg to use as data source
        """
        graph = Graph()
        graph.__operations = [deepcopy(ops.ReadIterFactory(name))]
        return graph

    @staticmethod
    def graph_from_file(filename: str, parser: tp.Callable[[str], ops.TRow]) -> "Graph":
        """Construct new graph extended with operation for reading rows from file
        Use ops.Read
        :param filename: filename to read from
        :param parser: parser from string to Row
        """
        graph = Graph()
        graph.__operations = [deepcopy(ops.Read(filename, parser))]
        return graph

    def map(self, mapper: ops.Mapper) -> "Graph":
        """Construct new graph extended with map operation with particular mapper
        :param mapper: mapper to use
        """
        self.__operations.append(ops.Map(mapper=mapper))
        return self

    def reduce(self, reducer: ops.Reducer, keys: tp.Sequence[str]) -> "Graph":
        """Construct new graph extended with reduce operation with particular reducer
        :param reducer: reducer to use
        :param keys: keys for grouping
        """
        self.__operations.append(ops.Reduce(keys=keys, reducer=reducer))
        return self

    def sort(self, keys: tp.Sequence[str], reverse: bool = False) -> "Graph":
        """Construct new graph extended with sort operation
        :param keys: sorting keys (typical is tuple of strings)
        :param reverse: reversed sort
        """
        self.__operations.append(ExternalSort(keys=keys, reverse=reverse))
        return self

    def join(self, joiner: ops.Joiner, join_graph: "Graph", keys: tp.Sequence[str]) -> "Graph":
        """Construct new graph extended with join operation with another graph
        :param joiner: join strategy to use
        :param join_graph: other graph to join with
        :param keys: keys for grouping
        """
        self.__operations.append(ops.Join(joiner=joiner, keys=keys))
        self.__graphs_for_join.append(join_graph)
        return self

    def run(self, **kwargs: tp.Any) -> ops.TRowsIterable:
        """Single method to start execution; data sources passed as kwargs"""
        operations = iter(self.__operations)
        graph = next(operations)(**kwargs)
        i = 0
        for operation in operations:
            if type(operation) == ops.Join:
                if len(self.__graphs_for_join):
                    table = self.__graphs_for_join[i].run(**kwargs)
                    graph = operation(graph, table)
                    i += 1
            else:
                graph = operation(graph)

        return graph


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import unittest

import lw_kw
import dd_kw
import dq_kw

KlasaOgolnaSzkieletuDat = dq_kw.KlasaOgolnaSzkieletuDat

class SzkieletDatDlaPoborow(KlasaOgolnaSzkieletuDat):
    def __init__(self, krt_pobor):
        '''
        SzkieletDatDlaPoborow:
        '''
        KlasaOgolnaSzkieletuDat.__init__(self)
        wymiar_czasowy = krt_pobor.krt_wymiar
        self.przypisz_szkielet(dq_kw.generator_szkieletu(wymiar_czasowy))
        self.wymiar_czasowy = wymiar_czasowy

    def to_pelna_godzina(self, akt):
        '''
        SzkieletDatDlaPoborow:
        '''
        return self.wymiar_czasowy == 24 or akt % 8 == 0

    def tekst_pelnej_godziny(self, akt):
        '''
        SzkieletDatDlaPoborow:
        '''
        if self.wymiar_czasowy == 24:
            result = akt
        else:
            result = akt / 4
        return str(result / 2)

class TestSzkieletowegoDatownika(unittest.TestCase):
    def test_energii_szkieletowego_datownika(self):
        '''
        TestSzkieletowegoDatownika:
        '''
        krt_pobor = dd_kw.CechaEnergii(lw_kw.Dm_Energy)
        obk = SzkieletDatDlaPoborow(krt_pobor)
        self.assertEqual(obk.szkielet_dat, dq_kw.generator_szkieletu(24))

    def test_mocy_szkieletowego_datownika(self):
        '''
        TestSzkieletowegoDatownika:
        '''
        krt_pobor = dd_kw.CechaEnergii(lw_kw.Dm_Power)
        obk = SzkieletDatDlaPoborow(krt_pobor)
        self.assertEqual(obk.szkielet_dat, dq_kw.generator_szkieletu(96))


'''This module defines the Player class. To get a brief description of the class,
use the following syntax: <module name as imported>.Player.__doc__'''

import pygame, random, math
import LineParams as line
import MoveFunctionsUpdated as move
import NonplayerClasses as np

class Player(np.Game):
    '''This class is a child class of Game, which is defined in the module
    NonplayerClass. It's also the parent class of Goalkeeper and Outfielder.
    Player has the following methods:
        __init__, load, setFootStartPos, adjustFootStartPos, blitFeet,
        blitBody, getStartPos, getCenter, setCenterPos, getCenterPos,
        getCorners, getRotation, getBodyAngle, getFootAngle,
        setMovingRotation, getMovingRotation, getDistMoved,
        getDistToBall, getEnding, feetToFront, move, chooseKickingFoot,
        kickBall, checkBallTouch, updateFeet, and updateAll.
    To get a brief description of each method, use the following syntax:
        <module name as imported>.Player.<method name>.__doc__'''
    def __init__(self, screenSize):
        '''This function initializes the class and sets its core attributes.'''
        np.Game.__init__(self, screenSize)   # initialize the parent class
        self.lFoot, self.rFoot, self.body = [None] * 3
        self.footSize = 20, 25
        self.bodySize = 64, 40
        self.strongFoot = random.choice(['lFoot', 'rFoot'])
        self.touchedBall = False

    def load(self, imageName1, imageName2):
        '''This function loads images of the player's foot and body into PyGame
        and rotates them 90 degrees counterclockwise.'''
        self.lFoot = self.loadImage(imageName1,self.footSize[1],self.footSize[0])
        self.body = self.loadImage(imageName2, self.bodySize[1],self.bodySize[0])
        # rotate 90 degrees clockwise
        self.lFoot = pygame.transform.rotate(self.lFoot, 90)
        self.rFoot = self.lFoot
        self.body = pygame.transform.rotate(self.body, 90)
        # holder variables for values at the start of the program (i.e.,
        # before any change/movement has been made)
        self.footStart, self.bodyStart = self.lFoot, self.body
        self.footStartCenter = self.footStart.get_rect().center
        self.bodyStartCenter = self.bodyStart.get_rect().center

    def setFootStartPos(self):
        '''This function sets the positions where the feet will be
        drawn, assuming that the player will be facing upward at the
        start of the program.'''
        # coordinates of the body center at the start of the program (i.e.,
        # before any change/movement has been made)
        self.bodyCenterPos = (self.bodyStartPos[0]+self.bodyStartCenter[0],
                              self.bodyStartPos[1]+self.bodyStartCenter[1])
        # positions of the feet
        self.betweenFeet = 8
        self.lFootStartPos = (
            self.bodyCenterPos[0]-self.getCenter()[0][0]*2-self.betweenFeet/2,
            self.bodyStartPos[1]+2)
        self.rFootStartPos = (self.bodyCenterPos[0]+self.betweenFeet/2,
                              self.lFootStartPos[1])
        # coordinates of the foot centers at the start of the program
        self.lFootCenterPos = (self.lFootStartPos[0]+self.footStartCenter[0],
                               self.lFootStartPos[1]+self.footStartCenter[1])
        self.rFootCenterPos = (self.rFootStartPos[0]+self.footStartCenter[0],
                               self.rFootStartPos[1]+self.footStartCenter[1])

    def adjustFootStartPos(self):
        '''This function adjusts the positions where the feet will be drawn at
        the start of the program. To do that, both the coordinates of the body
        center and those of the foot centers are adjusted.'''
        newBodyCenterPos = (self.bodyStartPos[0]+self.getCenter()[1][0],
                            self.bodyStartPos[1]+self.getCenter()[1][1])
        # distance from the old coordinates
        moveX, moveY = self.getDistMoved(newBodyCenterPos)
        self.setCenterPos('body', newBodyCenterPos[0], newBodyCenterPos[1])
        self.setCenterPos('lFoot', self.getCenterPos()[0][0]+moveX,
                          self.getCenterPos()[0][1]+moveY)
        self.setCenterPos('rFoot', self.getCenterPos()[1][0]+moveX,
                          self.getCenterPos()[1][1]+moveY)
        self.setMovingRotation(self.startRot)
        self.feetToFront()
        self.lFootStartPos = (
            self.getCenterPos()[0][0]-self.getCenter()[0][0],
            self.getCenterPos()[0][1]-self.getCenter()[0][1])
        self.rFootStartPos = (
            self.getCenterPos()[1][0]-self.getCenter()[0][0],
            self.getCenterPos()[1][1]-self.getCenter()[0][1])

    def blitFeet(self):
        '''This function rotates both the feet and the body and then draws only
        the feet onto the screen.
        rotate is the angle (measured in degrees) by which the feet will be
        rotated from the original upward rotation.'''
        self.setFootStartPos()   # where the feet will be drawn
        # rotate both feet and body
        self.lFoot = pygame.transform.rotate(self.lFoot, self.startRot)
        self.rFoot = pygame.transform.rotate(self.rFoot, self.startRot)
        self.body = pygame.transform.rotate(self.body, self.startRot)
        self.adjustFootStartPos()
        # draw feet
        self.screen.blit(self.lFoot, self.lFootStartPos)
        self.screen.blit(self.rFoot, self.rFootStartPos)
        self.things = [self.lFoot, self.rFoot]

    def blitBody(self):
        '''This function draws the body onto the screen.
        rotate is the angle (measured in degrees) by which the image will be
        rotated from the original upward rotation.'''
        self.screen.blit(self.body, self.bodyStartPos)
        self.things += [self.body]

    def getStartPos(self):
        '''This function returns the positions of the feet and the body at the
        start of the program.'''
        return [self.lFootStartPos, self.rFootStartPos, self.bodyStartPos]

    def getCenter(self):
        '''This function returns the centers of the feet and the body.'''
        footCenter = self.lFoot.get_rect().center
        bodyCenter = self.body.get_rect().center
        return footCenter, bodyCenter

    def setCenterPos(self, bodyPart, X, Y):
        '''This function sets a new position for the center of one of the feet
        or the center of the body.'''
        if bodyPart == 'lFoot':
            self.lFootCenterPos = X, Y
        elif bodyPart == 'rFoot':
            self.rFootCenterPos = X, Y
        else:
            self.bodyCenterPos = X, Y

    def getCenterPos(self):
        '''This function returns the coordinates of the centers of the feet
        and of the body.'''
        return self.lFootCenterPos, self.rFootCenterPos, self.bodyCenterPos

    def getCorners(self):
        '''This function returns a list containing the coordinates of the
        four corners of the player's body. The corners are listed in the
        following order: front left, front right, back left, and back right.
        Note that the size of the original image (before resizing) was
        (31, 22), and and that the image of the body has extra pixels along
        both the front and the back to account for the player's head.'''
        # number of extra pixels along each side (front/back)
        extraPix = 3 / 22 * self.bodyStart.get_rect().height
        # coordinates of the body center
        bodyCenterPos = self.getCenterPos()[2]
        # coordinates of the corners if the player were/is facing upward
        corner1 = (bodyCenterPos[0]-self.bodyStartCenter[0],
                   bodyCenterPos[1]-self.bodyStartCenter[1]+extraPix)
        corner2 = corner1[0]+self.bodySize[0], corner1[1]
        corner3 = corner1[0], corner1[1]+(self.bodyStartCenter[1]-extraPix)*2
        corner4 = corner2[0], corner3[1]
        corners = [corner1, corner2, corner3, corner4]
        # account for player's current rotation
        for i in range(len(corners)):
            corners[i] = move.rotate('right', corners[i], bodyCenterPos,
                                     step=self.getRotation())[0]
        return corners

    def getRotation(self):
        '''This function returns the player's current rotation, i.e., the
        direction the player is currently facing. It is an angle (measured in
        degrees) formed by two lines: (1) the line connecting the body center
        and the midpoint between the two foot centers, and (2) the y-axis
        pointing downward from the midpoint.'''
        # coordinates of the midpoint between the two foot centers
        midpoint = ((self.getCenterPos()[0][0]+self.getCenterPos()[1][0])/2,
                    (self.getCenterPos()[0][1]+self.getCenterPos()[1][1])/2)
        # current rotation
        currentRot = line.getParams(midpoint, self.getCenterPos()[2])[3]
        return currentRot

    def getBodyAngle(self, ball):
        '''This function returns the angle (measured in degrees) of the body
        with respect to the y-axis pointing downward from the ball.'''
        return line.getParams(ball.getCenterPos(), self.getCenterPos()[2])[3]

    def getFootAngle(self, ball):
        '''This function returns the angles (measured in degrees) of the feet
        with respect to the y-axis pointing downward from the ball.'''
        left = line.getParams(ball.getCenterPos(), self.getCenterPos()[0])[3]
        right = line.getParams(ball.getCenterPos(), self.getCenterPos()[1])[3]
        return left, right

    def setMovingRotation(self, rotate):
        '''This function sets the angle (measured in degrees) by which the
        rotation of the player has changed, after a movement, from that at the
        start of the program.'''
        self.rotate = rotate

    def getMovingRotation(self):
        '''This function returns the angle (measured in degrees) by which the
        rotation of the player has changed, after a movement, from that at the
        start of the program.'''
        return self.rotate

    def getDistMoved(self, newCenterPos):
        '''This function returns the change in the position of
        the body after a movement.
        newCenterPos is the new coordinates of the body center.'''
        return line.getParams(self.getCenterPos()[2], newCenterPos)[:2]

    def getDistToBall(self, ball):
        '''This function returns the distance from the ball to each foot and
        to the body.'''
        lFoot = line.getParams(ball.getCenterPos(), self.getCenterPos()[0])[2]
        rFoot = line.getParams(ball.getCenterPos(), self.getCenterPos()[1])[2]
        body = line.getParams(ball.getCenterPos(), self.getCenterPos()[2])[2]
        return lFoot, rFoot, body

    def getEnding(self, bodyPart, ball, finalDist):
        '''This function returns the point to which the body/foot will move
        when it's headed for the ball, along with the direction the body/foot
        will face when it reaches the endpoint (angle measured in degrees).
        finalDist is the distance between the center of the body/foot and
        the ball center when the body/foot is at the target point.'''
        if 'Foot' in bodyPart:
            if bodyPart == 'lFoot':
                angle = self.getFootAngle(ball)[0]
            else:
                angle = self.getFootAngle(ball)[1]
        else:
            angle = self.getBodyAngle(ball)
        # point to which the body will move
        endPointX = ball.getCenterPos()[0] + finalDist * np.getTrig(angle)[0]
        endPointY = ball.getCenterPos()[1] + finalDist * np.getTrig(angle)[1]
        endPoint = endPointX, endPointY
        # final rotation, i.e., direction the body will face when it reaches
        # the endpoint (measured in degrees)
        endAngle = line.getParams(ball.getCenterPos(), endPoint)[3]
        return endPoint, endAngle

    def feetToFront(self):
        '''This function moves the feet to the front of the body.
        target is either the coordinates of the point around which the player
        rotates or the coordinates of the point to which the player moves.'''
        currentRot = self.getRotation()   # measured in degrees
        # move feet
        self.lFootCenterPos = move.rotate(
            'right', self.getCenterPos()[0], self.getCenterPos()[2],
            step=self.getMovingRotation()-currentRot)[0]
        self.rFootCenterPos = move.rotate(
            'right', self.getCenterPos()[1], self.getCenterPos()[2],
            step=self.getMovingRotation()-currentRot)[0]

    def move(self, moveType, direction, ball):
        '''This function moves the player in one of three ways: in a straight
        line, straight toward the ball, or in a circle around the ball.'''
        # move body
        if moveType == 'straight':
            newCenterPos, rotate = move.straight(
                direction,self.getCenterPos()[2],objCenter=self.getCenter()[1],
                screenSize=(self.screenWidth,self.screenHeight))
        elif moveType == 'to ball':
            finalDist = self.bodyStartCenter[1] + ball.center[1]
            endPoint, endAngle = self.getEnding('body', ball, finalDist)
            newCenterPos, rotate = move.toPoint(self.getCenterPos()[2],
                                                endPoint, endAngle, 3)
        elif moveType == 'circle':
            bodyAngle = self.getBodyAngle(ball)
            newCenterPos, rotate = move.rotate(
                direction, self.getCenterPos()[2], ball.getCenterPos(),
                screenSize=(self.screenWidth,self.screenHeight),
                objCenter=self.getCenter()[1])
        else:
            newCenterPos = self.getCenterPos()[2]
        if newCenterPos != self.getCenterPos()[2]:
            self.moved = True
            moveX, moveY = self.getDistMoved(newCenterPos)
            self.setCenterPos('body', newCenterPos[0], newCenterPos[1])
            self.setMovingRotation(rotate)
            # move feet at the same distance as body
            self.setCenterPos('lFoot', self.getCenterPos()[0][0]+moveX,
                              self.getCenterPos()[0][1]+moveY)
            self.setCenterPos('rFoot', self.getCenterPos()[1][0]+moveX,
                              self.getCenterPos()[1][1]+moveY)
            if self.getRotation() != self.getMovingRotation():
                # player facing the wrong direction
                self.feetToFront()

    def chooseKickingFoot(self, ball):
        '''This function chooses the foot that will kick the ball and returns:
        (1) a string indicating the foot,
        (2) the coordinates of the foot's center point, and
        (3) the distance between the ball and that foot.'''
        lFootToBall, rFootToBall = self.getDistToBall(ball)[:2]
        if lFootToBall < rFootToBall:
            return 'lFoot', self.getCenterPos()[0], lFootToBall
        elif lFootToBall > rFootToBall:
            return 'rFoot', self.getCenterPos()[1], rFootToBall
        else:   # ball is equidistant from both feet
            if self.strongFoot == 'lFoot':
                return self.strongFoot, self.getCenterPos()[0], lFootToBall
            else:
                return self.strongFoot, self.getCenterPos()[1], rFootToBall

    def kickBall(self, ball, gk=False):
        '''This function moves one of the feet to kick the ball.
        gk denotes whether or not the player is the goalkeeper.
        If he is, he only kicks the ball when it's nearby. If not, he
        only kicks the ball when it's not in the goalkeeper's possession.'''
        currentRot = self.getRotation()   # measured in degrees
        kickingFoot, kFootCenterPos, distToBall = self.chooseKickingFoot(ball)
        if kickingFoot == 'lFoot':
            endAngle = self.getFootAngle(ball)[0]
        else:
            endAngle = self.getFootAngle(ball)[1]
        minDist = self.footStartCenter[1] + ball.center[1]
        if distToBall <= minDist:
            endPoint = kFootCenterPos
        else:
            endPoint = self.getEnding(kickingFoot, ball, minDist)[0]
        # move foot
        newKFootCenterPos, kFootRotate = move.toPoint(kFootCenterPos,
                                                      endPoint, endAngle)
        if newKFootCenterPos == endPoint:
            self.touchedBall = True
        else:
            self.touchedBall = False
        if newKFootCenterPos != kFootCenterPos:
            if (gk and self.touchedBall) or \
               ((not gk) and (not ball.gkCaught) and (distToBall <= minDist*2)):
                if kickingFoot == 'lFoot':
                    newCenterPos = newKFootCenterPos, self.getCenterPos()[1]
                    rotate = kFootRotate, currentRot
                else:
                    newCenterPos = self.getCenterPos()[0], newKFootCenterPos
                    rotate = currentRot, kFootRotate
                self.updateFeet(kickingFoot, newCenterPos, rotate)
                self.updateDisplay()
                pygame.time.wait(100)   # pause program for 100 ms
                # bring foot back to its position and rotation before the kick
                if kickingFoot == 'lFoot':
                    newCenterPos = kFootCenterPos, self.getCenterPos()[1]
                else:
                    newCenterPos = self.getCenterPos()[0], kFootCenterPos
                self.updateFeet(kickingFoot, newCenterPos, (currentRot,)*2)

    def updateFeet(self, foot, newCenterPos, rotate):
        '''This function updates the positions and rotations of only the feet.
        newCenterPos is a tuple/list of the new coordinates of the
        center of each foot.
        rotate is an array of the angles (measured in degrees) by which
        the rotations of the feet have changed from those at the start of
        the program.'''
        moved = self.lFoot, self.rFoot, self.footStart, self.footStart
        lFootIndex = self.allThings.index(self.lFoot)
        move.update(self.screen, self.allThings, self.allPos, moved,
                    newCenterPos, rotate)
        self.lFoot, self.rFoot = self.allThings[lFootIndex:lFootIndex+2]

    def updateAll(self):
        '''This function updates the positions and rotations of both the body
        and the feet.'''
        moved = (self.lFoot, self.rFoot, self.body,
                 self.footStart, self.footStart, self.bodyStart)
        newCenterPos = self.getCenterPos()
        lFootIndex = self.allThings.index(self.lFoot)
        bodyIndex = self.allThings.index(self.body)
        move.update(self.screen, self.allThings, self.allPos, moved,
                    newCenterPos, rotate=(self.getMovingRotation(),)*3)
        # new values
        self.lFoot, self.rFoot = self.allThings[lFootIndex:lFootIndex+2]
        self.body = self.allThings[bodyIndex]

class Goalkeeper(Player):
    '''This class is a child class of Player and has the following methods:
    __init__ and moveAcross.
    To get a brief description of each method, use the following syntax:
        <module name as imported>.Goalkeeper.<method name>.__doc__'''
    def __init__(self, screenSize):
        '''This function initializes the class and sets its core attributes.'''
        Player.__init__(self, screenSize)   # initialize the parent class
        self.bodyStartPos = (self.screenWidth-76)/2, 80
        self.startRot = 180   # measured in degrees
        self.direction = random.choice([1, -1])   # right or left
        self.speed = 5   # number of pixels per movement

    def moveAcross(self, goal):
        '''This function makes the goalkeeper move between the goal posts,
        only stopping when he catches the ball (i.e., when the ball hits
        the front of his body).'''
        currentRot = self.getRotation()   # measured in degrees
        # points to which the player will move
        lEndPoint = goal.getPosts()[0] + self.getCenter()[1][0]
        rEndPoint = goal.getPosts()[1] - self.getCenter()[1][0]
        if self.direction == 1:   # playing moving to the right
            if self.getCenterPos()[2][0] >= rEndPoint:   # reached right post
                self.direction = -1
        else:   # player moving left
            if self.getCenterPos()[2][0] <= lEndPoint:   # reached left post
                self.direction = 1
        # move player
        self.setCenterPos('body',
                          self.getCenterPos()[2][0]+self.speed*self.direction,
                          self.getCenterPos()[2][1])
        self.setCenterPos('lFoot',
                          self.getCenterPos()[0][0]+self.speed*self.direction,
                          self.getCenterPos()[0][1])
        self.setCenterPos('rFoot',
                          self.getCenterPos()[1][0]+self.speed*self.direction,
                          self.getCenterPos()[1][1])
        self.updateAll()

class Outfielder(Player):
    '''This class is a child class of Player and has only one mthod: __init__.
    To get a brief description of each method, use the following syntax:
        <module name as imported>.Outfielder.<method name>.__doc__'''
    def __init__(self, screenSize):
        '''This function initializes the class and sets its core attributes.'''
        Player.__init__(self, screenSize)   # initialize the parent class
        bodyStartPosX = random.uniform(5, self.screenWidth-5-self.bodySize[0])
        bodyStartPosY = random.uniform(100,self.screenHeight-5-self.bodySize[1])
        self.bodyStartPos = bodyStartPosX, bodyStartPosY
        self.startRot = 0
        self.moved = False


import requests
from fake_useragent import UserAgent
import pandas as pd
from bs4 import BeautifulSoup as bs

ua = UserAgent()
headers = {
    'User-Agent': ua.random
}

url_chinatimes = "https://www.chinatimes.com/?chdtv"
res_chinatimes = requests.get(url=url_chinatimes, headers=headers)
soup_chinatimes = bs(res_chinatimes.text,'lxml')
focus_news = soup_chinatimes.select('li.col-md-6')

title = [i.select('h3.title')[0].text for i in focus_news]
urls = [i.select('h3.title')[0].a['href'] for i in focus_news]
category = [i.select('div.category')[0].text for i in focus_news]
time_ = [i.select('time')[0].text for i in focus_news]

zipped = zip(title,urls,category,time_)
df_chinatimes = pd.DataFrame(list(zipped), columns=['title', 'url','tags','time'])
print(df_chinatimes)


ui_restart_server = False

SELECTION_FACES_DATA = None
ui_SELECTED_INPUT_FACE_INDEX = 0

ui_selected_enhancer = None
ui_blend_ratio = None
ui_input_thumbs = []
ui_target_thumbs = []

ui_live_cam_active = False


import sqlite3

conn = sqlite3.connect('database.db')

c = conn.cursor()
# c.execute("""CREATE TABLE mobie(
#     use_name varchar(32),
#     call_duration int
# )""")
c.execute("delete  FROM mobie ")

conn.commit()
conn.close()


import random

AANTAL_RONDES = 20
AANTAL_POGINGEN = 10
ronde = 0
score = 0
while ronde < AANTAL_RONDES:
    raden = input("Ben je er klaar voor om het getal te raden? ").lower()

    if raden == "nee":
        print(f"""Helaas!
        Uw score is {score} van de {AANTAL_RONDES} punten!""")
        exit()

    geheimgetal = random.randint(1, 1000)
#   print(geheimgetal)  # Deze print is er voor om te kijken of het script goed werkt en is dus niet noodzakelijk
    poging = 0
    while poging < AANTAL_POGINGEN:  # loop van het getal raden stopt na 10 pogingen
        while True:
            try:  # verplichting van cijfers
                antwoord = int(input("Raad het getal: "))
                break  # loop and a half
            except ValueError:
                print("Alleen cijfers invullen aub!")

        if antwoord == geheimgetal:
            print("Je heb het goede getal geraden!")
            score += 1
            break
        else:  # abs gebruiken
            verschil = abs(antwoord - geheimgetal)
            if verschil <= 20:  # berekent hier of het heel warm is of warm
                print("Je bent heel dichtbij!")
            elif verschil <= 50 and verschil >= 20:
                print("Je bent dichtbij!")
        poging += 1

    print(f"Je hebt {score} punt(en)!")
    ronde += 1

print(f"Uw score is {score} van de {AANTAL_RONDES} punten!")


from chatterbot import ChatBot #import the chatbot
from chatterbot.trainers import ChatterBotCorpusTrainer
import os

import logging
logger = logging.getLogger()
logger.setLevel(logging.ERROR)

bot = ChatBot("Bot", preprocessors=["chatterbot.preprocessors.clean_whitespace"]) #"mypreprocessors.fix_typos_in_statement"
trainer = ChatterBotCorpusTrainer(bot)

corpus_path='F:/BackUpMyData/MySVNRepo/MyData/Tech_TargetLearns/Machine_Learning/Workspaces/MyBot/data/english/'

while True:
	message = input('You:')
	if message.strip() == 'Bye':
		print('ChatBot: Bye')
		break
	else:
		reply = bot.get_response(message)
		print('ChatBot:', reply)


import os
import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.multiclass import OneVsRestClassifier
import warnings

class MultiClassiflier:
    def predict(self,reviews):
        dir = os.path.dirname(__file__)
        tt = pd.read_csv(dir + '/Data/TrainingSet/Data.csv', sep=",")
        arrayData = [var for var in tt["name"] if var]
        X_train = np.array(arrayData)
        #print(X_train)
        #print(len(arrayData))
        #y_train = [[0],[0],[0],[0],[0],[0],[1],[1],[1],[1],[1],[1],[0,1],[0,1]]
        y_train = []
        categoryData = [var for var in tt["category"] if var]
        for ids in categoryData:
            indexarry=[]
            splitIds = str(ids).split(',')
            for id in splitIds:
                indexarry.append(int(id))
            #print(indexarry)
            y_train.append(indexarry)
        X_test = np.array(reviews)
        catData = pd.read_csv(dir + '/Data/TrainingSet/Categories.csv', sep=",")
        target_names = list(catData["CategoryName"])
        #target_names = ['Food', 'Fruit','Nuts','Vegetable','Desert','Soup']

        classifier = Pipeline([
            ('vectorizer', CountVectorizer()),
            ('tfidf', TfidfTransformer()),
            ('clf', OneVsRestClassifier(LinearSVC()))])
        classifier.fit(X_train, y_train)
        predicted = classifier.predict(X_test)
        for item, labels in zip(X_test, predicted):
            print('%s => %s' % (item, ', '.join(target_names[x] for x in labels)))


from auto_surprise.constants import AVAILABLE_METRICS
from auto_surprise.exceptions import ValidationError
from surprise.dataset import DatasetAutoFolds

def validate_target_metric(metric):
    if metric not in AVAILABLE_METRICS:
        raise ValidationError(
            "target_metric",
            'Unknown target metric : "%s". Must be in %s' % (metric, AVAILABLE_METRICS),
        )
    else:
        return True

def validate_dataset(data):
    """
    Validate user given dataset
    """
    if data:
        if not isinstance(data, DatasetAutoFolds):
            raise ValidationError(
                "data",
                'Unknown data format. Must be and instance of "DatasetAutoFolds". Got "%s"'
                % type(data),
            )
        else:
            return True
    else:
        raise ValidationError("data", "Data must be present. Got: %s" % data)

def validate_max_evals(max_evals):
    """
    Max evaluations for hyperparameter tuning. Must be an unsigned integer greater than 0
    """
    if not isinstance(max_evals, int) or not max_evals > 0:
        raise ValidationError(
            "max_evals",
            "max_evals must be an unsigned integer greater than 0. Got {0}".format(
                max_evals
            ),
        )
    else:
        return True

def validate_cpu_time_limit(cpu_time_limit):
    """
    Execution time limit. Must be an unsigned integer greater than 0
    """
    if not isinstance(cpu_time_limit, int) or not cpu_time_limit > 0:
        raise ValidationError(
            "cpu_time_limit",
            "cpu_time_limit must be an unsigned integer greater than 0. Got {0}".format(
                cpu_time_limit
            ),
        )
    else:
        return True


import numpy as np
import pylab as pl
from matplotlib import collections  as mc
import matplotlib.pyplot as plt
import os, sys

filea = open(os.getcwd() + '\\' + sys.argv[1])
a = filea.readlines()

x = [0]*len(a)
y = [0]*len(a)
for i,line in enumerate(a):
    b = line.split(' ')
    x[i] = float(b[0])
    y[i] = float(b[1])

expWidth = int(sys.argv[1].split("-")[1])
expHeight = expWidth/4
plt.scatter(x,y,s=0.9)
#plt.normalize
plt.title('Input points for SSSP tree')
plt.xlim(-0.1,expWidth+0.1)
plt.ylim(-0.1,expHeight+0.1)
plt.xlabel('x')
plt.ylabel('y')
plt.show()


import gettext
import os
import tempfile
import time
import xml.dom.minidom

from otopi import plugin
from otopi import util

from ovirt_setup_lib import dialog

from ovirt_hosted_engine_setup import constants as ohostedcons
from ovirt_hosted_engine_setup import domains as ohosteddomains

def _(m):
    return gettext.dgettext(message=m, domain='ovirt-hosted-engine-setup')

@util.export
class Plugin(plugin.PluginBase):
    """
    NFS / GlusterFS storage plugin.
    """

    UMOUNT_TRIES = 10

    def __init__(self, context):
        super(Plugin, self).__init__(context=context)
        self._checker = ohosteddomains.DomainChecker()
        # TODO: remove once the engine is able to handle this
        self.query_for_additional_mnt_options = False

    def _mount(self, path, connection, domain_type, mnt_options):
        fstype = ''
        opts = []

        if domain_type == ohostedcons.DomainTypes.NFS3:
            fstype = ohostedcons.FileSystemTypes.NFS
            opts.append('vers=3')
        elif domain_type == ohostedcons.DomainTypes.NFS4:
            fstype = ohostedcons.FileSystemTypes.NFS
            opts.append('vers=4')
        elif domain_type == ohostedcons.DomainTypes.GLUSTERFS:
            fstype = ohostedcons.FileSystemTypes.GLUSTERFS

        if fstype == ohostedcons.FileSystemTypes.NFS:
            opts.append('retry=1')

        mount_cmd = (
            self.command.get('mount'),
            '-t%s' % fstype,
        )

        if mnt_options:
            opts.extend(
                mnt_options.split(',')
            )

        if opts:
            mount_cmd += (
                '-o%s' % ','.join(opts),
            )

        mount_cmd += (
            connection,
            path,
        )

        rc, _stdout, stderr = self.execute(
            mount_cmd,
            raiseOnError=False,
            env={
                'LC_ALL': 'C',
            },

        )
        error = '\n'.join(stderr)
        if rc != 0:
            self.logger.error(
                _(
                    'Error while mounting specified storage path: {error}'
                ).format(
                    error=error,
                )
            )
            raise RuntimeError(error)

    def _umount(self, path):
        rc = -1
        tries = self.UMOUNT_TRIES
        while tries > 0:
            rc, _stdout, _stderr = self.execute(
                (
                    self.command.get('umount'),
                    path
                ),
                raiseOnError=False,
                env={
                    'LC_ALL': 'C',
                },
            )
            if rc == 0:
                tries = -1
            else:
                tries -= 1
                time.sleep(1)
                # rc, stdout and stderr are automatically logged as debug
                self.execute(
                    (
                        self.command.get('lsof'),
                        '+D%s' % path,
                        '-xfl'
                    ),
                    raiseOnError=False,
                    env={
                        'LC_ALL': 'C',
                    },
                )
        return rc

    def _check_domain_rights(self, path):
        rc, _stdout, _stderr = self.execute(
            (
                self.command.get('sudo'),
                '-u', 'vdsm',
                '-g', 'kvm',
                'test',
                '-r', path,
                '-a',
                '-w', path,
                '-a',
                '-x', path,
            ),
            raiseOnError=False
        )
        if rc != 0:
            raise RuntimeError(
                _(
                    'permission settings on the specified storage do not '
                    'allow access to the storage to vdsm user and kvm group. '
                    'Verify permission settings on the specified storage '
                    'or specify another location'
                )
            )

    def _check_volume_properties(self, connection):
        server, volume = connection.split(':')
        if volume[0] == '/':
            volume = volume[1:]
        glustercmd = self.command.get('gluster')
        rc, stdout, stderr = self.execute(
            args=(
                glustercmd,
                '--mode=script',
                '--xml',
                'volume',
                'info',
                volume,
                '--remote-host=%s' % server,
            ),
            raiseOnError=True
        )
        if rc != 0:
            self.logger.error(_('Failed to retrieve Gluster Volume info'))
            raise RuntimeError(
                'Failed to retrieve Gluster Volume info: ' + str(stdout)
            )
        self.logger.debug('Gluster Volume info XML output: ' + str(stdout))
        dom = xml.dom.minidom.parseString(''.join(stdout))
        cliOutput = dom.getElementsByTagName('cliOutput')[0]
        opRet = (
            cliOutput.getElementsByTagName('opRet')[0]
        ).firstChild.nodeValue
        opErrno = (
            cliOutput.getElementsByTagName('opErrno')[0]
        ).firstChild.nodeValue
        opErrstrElement = cliOutput.getElementsByTagName('opErrstr')[0]
        opErrstr = ' '.join(
            t.nodeValue for t in opErrstrElement.childNodes
            if t.nodeType == t.TEXT_NODE
        )

        if opRet != '0':
            self.logger.error(_('Failed to retrieve Gluster Volume info'))
            raise RuntimeError(
                'Failed to retrieve Gluster Volume info '
                '[{code}]: {error}'.format(
                    code=opErrno,
                    error=opErrstr,
                )
            )
        volInfo = cliOutput.getElementsByTagName('volInfo')[0]
        volumes = volInfo.getElementsByTagName('volumes')[0]
        volCount = (
            volumes.getElementsByTagName('count')[0]
        ).firstChild.nodeValue
        if volCount != '1':
            raise RuntimeError(
                _('GlusterFS Volume {volume} does not exist!').format(
                    volume=volume,
                )
            )
        volume = volumes.getElementsByTagName('volume')[0]
        replicaCount = (
            volume.getElementsByTagName('replicaCount')[0]
        ).firstChild.nodeValue
        if replicaCount != '3':
            raise RuntimeError(
                _(
                    'GlusterFS Volume is not using replica 3'
                )
            )
        self.logger.info(_('GlusterFS replica 3 Volume detected'))
        host_list = []
        for brickE in volume.getElementsByTagName('brick'):
            host_list.append(
                (brickE.getElementsByTagName('hostUuid')[0])
                .firstChild.nodeValue
            )
        if len(set(host_list)) < 3:
            self.logger.warning(_(
                'Three distinct hosts are required for '
                'safe and reliable operations'
            ))
        status = (
            volume.getElementsByTagName('status')[0]
        ).firstChild.nodeValue
        statusStr = (
            volume.getElementsByTagName('statusStr')[0]
        ).firstChild.nodeValue
        if status != '1':
            raise RuntimeError(
                _(
                    "GlusterFS Volume is '{statusStr}', "
                    "please ensure that it's started"
                ).format(
                    statusStr=statusStr,
                )
            )

    def _fix_path_syntax(self):
        path = self.environment[
            ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
        ]
        if (
            path and
            len(path) > 2 and
            path[-1] == '/' and
            path[-2] == ':'
        ):
            raise RuntimeError(
                _(
                    "'server:/' is not an acceptable export path, "
                    "please use at least one subdirectory"
                )
            )
        path = os.path.normpath(
            self.environment[
                ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
            ]
        )
        if path != self.environment[
            ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
        ]:
            self.logger.warning(
                _(
                    "Fixing path syntax: "
                    "replacing '{original}' with '{fixed}'"
                ).format(
                    original=self.environment[
                        ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
                    ],
                    fixed=path,
                )
            )
            self.environment[
                ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
            ] = path

    def _validateDomain(
        self,
        connection,
        domain_type,
        check_space,
        mnt_options,
    ):
        if self.environment[
            ohostedcons.StorageEnv.DOMAIN_TYPE
        ] == ohostedcons.DomainTypes.GLUSTERFS:
            self._check_volume_properties(connection)
        path = tempfile.mkdtemp()
        try:
            self._mount(path, connection, domain_type, mnt_options)
            self._checker.check_valid_path(path)
            self._check_domain_rights(path)
            self._checker.check_base_writable(path)
            if check_space:
                self._checker.check_available_space(
                    path,
                    ohostedcons.Const.MINIMUM_SPACE_STORAGEDOMAIN_MB
                )
        finally:
            if self._umount(path) == 0:
                os.rmdir(path)
            else:
                self.logger.warning(
                    _('Cannot unmount {path}').format(
                        path=path,
                    )
                )

    @plugin.event(
        stage=plugin.Stages.STAGE_SETUP,
    )
    def _setup(self):
        self.command.detect('lsof')
        self.command.detect('sudo')
        self.command.detect('mount')
        self.command.detect('umount')
        self.command.detect('gluster')

    @plugin.event(
        stage=plugin.Stages.STAGE_CUSTOMIZATION,
        name=ohostedcons.Stages.CONFIG_STORAGE_NFS,
        after=(
            ohostedcons.Stages.CONFIG_STORAGE_EARLY,
        ),
        before=(
            ohostedcons.Stages.CONFIG_STORAGE_LATE,
        ),
        condition=lambda self: (
            self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE] in (
                ohostedcons.DomainTypes.GLUSTERFS,
                ohostedcons.DomainTypes.NFS3,
                ohostedcons.DomainTypes.NFS4,
            )
        ),
    )
    def _customization(self):
        if self.environment[
            ohostedcons.StorageEnv.DOMAIN_TYPE
        ] == ohostedcons.DomainTypes.GLUSTERFS:
            self.logger.info(
                _(
                    'Please note that Replica 3 support is required for '
                    'the shared storage.'
                )
            )
            self.query_for_additional_mnt_options = True
        interactive = self.environment[
            ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
        ] is None
        validDomain = False
        while not validDomain:
            if interactive:
                self.environment[
                    ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
                ] = self.dialog.queryString(
                    name='OVEHOSTED_STORAGE_DOMAIN_CONNECTION',
                    note=_(
                        'Please specify the full shared storage '
                        'connection path to use (example: host:/path): '
                    ),
                    prompt=True,
                    caseSensitive=True,
                )
                if self.query_for_additional_mnt_options:
                    mnt_options = self.environment[
                        ohostedcons.StorageEnv.MNT_OPTIONS
                    ]
                    self.environment[
                        ohostedcons.StorageEnv.MNT_OPTIONS
                    ] = self.dialog.queryString(
                        name='OVEHOSTED_STORAGE_DOMAIN_MNT_OPTIONS',
                        note=_(
                            'If needed, specify additional mount options for '
                            'the connection to the hosted-engine storage'
                            'domain [@DEFAULT@]: '
                        ),
                        prompt=True,
                        caseSensitive=True,
                        default=mnt_options if mnt_options else '',
                    )
            try:
                self._fix_path_syntax()
                self._validateDomain(
                    connection=self.environment[
                        ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
                    ],
                    domain_type=self.environment[
                        ohostedcons.StorageEnv.DOMAIN_TYPE
                    ],
                    check_space=False,
                    mnt_options=self.environment[
                        ohostedcons.StorageEnv.MNT_OPTIONS
                    ],
                )
                validDomain = True
            except (ValueError, RuntimeError) as e:
                if interactive:
                    self.logger.debug('exception', exc_info=True)
                    self.logger.error(
                        _(
                            'Cannot access storage connection '
                            '{connection}: {error}'
                        ).format(
                            connection=self.environment[
                                ohostedcons.StorageEnv.
                                STORAGE_DOMAIN_CONNECTION
                            ],
                            error=e,
                        )
                    )
                else:
                    raise e
            except ohosteddomains.InsufficientSpaceError as e:
                self.logger.debug('exception', exc_info=True)
                self.logger.debug(e)
                min_requirement = '%0.2f' % (
                    ohostedcons.Const.MINIMUM_SPACE_STORAGEDOMAIN_MB / 1024.0
                )
                if interactive:
                    self.logger.error(
                        _(
                            'Storage domain for self hosted engine '
                            'is too small: '
                            'you should have at least {min_r} GB free'.format(
                                min_r=min_requirement,
                            )
                        )
                    )
                else:
                    raise RuntimeError(
                        _(
                            'Storage domain for self hosted engine '
                            'is too small: '
                            'you should have at least {min_r} GB free'.format(
                                min_r=min_requirement,
                            )
                        )
                    )

    @plugin.event(
        stage=plugin.Stages.STAGE_CUSTOMIZATION,
        name=ohostedcons.Stages.CONFIG_STORAGE_HC,
        after=(
            ohostedcons.Stages.CONFIG_STORAGE_NFS,
        ),
        before=(
            ohostedcons.Stages.CONFIG_STORAGE_LATE,
        ),
        condition=lambda self: (
            self.environment[
                ohostedcons.StorageEnv.DOMAIN_TYPE
            ] == ohostedcons.DomainTypes.GLUSTERFS
        ),
    )
    def _customization_hc(self):
        if self.environment[
            ohostedcons.StorageEnv.ENABLE_HC_GLUSTER_SERVICE
        ] is None:
            self.environment[
                ohostedcons.StorageEnv.ENABLE_HC_GLUSTER_SERVICE
            ] = dialog.queryBoolean(
                dialog=self.dialog,
                name='ENABLE_HC_GLUSTER_SERVICE',
                note=_(
                    'Do you want to configure this host and '
                    'its cluster for gluster? '
                    '(@VALUES@) [@DEFAULT@]: '
                ),
                prompt=True,
                default=False,
            )

    @plugin.event(
        stage=plugin.Stages.STAGE_CUSTOMIZATION,
        after=(
            ohostedcons.Stages.CONFIG_STORAGE_LATE,
        ),
        before=(
            ohostedcons.Stages.DIALOG_TITLES_E_STORAGE,
        ),
        condition=lambda self: (
            self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE] in (
                ohostedcons.DomainTypes.GLUSTERFS,
                ohostedcons.DomainTypes.NFS3,
                ohostedcons.DomainTypes.NFS4,
            )
        ),
    )
    def _late_customization(self):
        # On first host we need to check if we have enough space too.
        # We must skip this check on additional hosts because the space is
        # already filled with the Hosted Engine VM image.
        # Sadly we can't go back to previous customization stage so here
        # we can only fail the setup.
        try:
            self._validateDomain(
                connection=self.environment[
                    ohostedcons.StorageEnv.STORAGE_DOMAIN_CONNECTION
                ],
                domain_type=self.environment[
                    ohostedcons.StorageEnv.DOMAIN_TYPE
                ],
                check_space=True,
                mnt_options=self.environment[
                    ohostedcons.StorageEnv.MNT_OPTIONS
                ],
            )
        except ohosteddomains.InsufficientSpaceError as e:
            self.logger.debug('exception', exc_info=True)
            self.logger.debug(e)
            min_requirement = '%0.2f' % (
                ohostedcons.Const.MINIMUM_SPACE_STORAGEDOMAIN_MB / 1024.0
            )
            raise RuntimeError(
                _(
                    'Storage domain for self hosted engine '
                    'is too small: '
                    'you should have at least {min_r} GB free'.format(
                        min_r=min_requirement,
                    )
                )
            )

# vim: expandtab tabstop=4 shiftwidth=4


from flask import make_response, request
from datetime import datetime
from functools import wraps
import sys
import traceback
import requests
import asyncio
import aiohttp
import socket

class Logger:
	"""
	An instance of the :class:`Logger` object is created in the main module or the `__init__` file like this::

		logger = Logger(app, accessKey, [config_object: optional])

	`app` is the instance of the current Flask application.
	`accessKey` is the generated key associated with the Flask application.
	`config_object` is a dict that contains configuration values for the instance of the `Logger` object. It can be one or either of the following:
		config_object["LOG_TYPE"]
		config_object["DO_NOT_LOG"]

	The following Flask application configuration values MUST be set::

		app.config["LOGGING_URL"]
		app.config["LOG_AUTH_KEY"]
	Without the above configuration values, the object shall not be successfully created and an exception shall be raised.
	"""

	def log(self):
		"""
		This is responsible for actually posting the logging data to the external service.\
		Depending on the "LOG_TYPE" set, it is either implemented as a function wrapper or called in the `__init__` file.
		"""

		header_dict = dict(request.headers)

		try:
			tracker_id = header_dict["tracker_id"]
		except Exception:
			tracker_id = None

		try:
			user_agent = header_dict["User-Agent"]
		except Exception:
			user_agent = None

		try:
			language = header_dict["Accept-Language"]
		except Exception:
			language = None

		try:
			referer = header_dict["Referer"]
		except Exception:
			referer = None

		try:
			origin = header_dict["Origin"]
		except Exception:
			origin = None

		try:
			json_data = request.json
		except Exception:
			json_data = None

		try:
			platform = request.user_agent.platform.title()
		except Exception:
			platform = None

		try:
			browser = request.user_agent.browser.title()
		except Exception:
			browser = None

		try:
			auth_header_token = header_dict["Authorization"].split(" ")[1]
		except Exception:
			auth_header_token = None

		## If set to run before a request: This is the default setting
		if self.pre_request:
			@self.app.before_request()
			def run():
				## If the path accessed is in the do_not_log list, it is skipped
				if request.path in self.do_not_log:
					return
				## If the path accessed is not in the do_not_log list, it is posted
				else:
					post_data = {
						"error": None,
						"stack_trace": None,
						"method": request.method,
						"source_ip": request.remote_addr,
						"url": request.url,
						"status_code": 200, ## Assumed to be 200 due to the nature of the function
						"headers": str(header_dict),
						"user_agent": user_agent,
						"language": language,
						"platform": platform,
						"browser": browser,
						"referer": referer,
						"origin": origin,
						"auth_header": auth_header_token,
						"access_time": datetime.now().strftime("%A, %d %B %Y %H:%M:%S"),
						"logging_access_key": self.accessKey,
						"json": json_data,
						"request_params": str(dict(request.args))
					}

					self.startPost(post_data)

					return

			return run

		## If set to as a wrapper to a function
		else:
			def log_decorator(func):

				@wraps(func)
				def execute(*args, **kwargs):
					try:
						result = func(*args, **kwargs)

						result_response = make_response(result)

						post_data = {
							"error": None,
							"stack_trace": None,
							"method": request.method,
							"source_ip": request.remote_addr,
							"url": request.url,
							"status_code": result_response.status_code,
							"headers": str(header_dict),
							"user_agent": user_agent,
							"language": language,
							"platform": platform,
							"browser": browser,
							"referer": referer,
							"origin": origin,
							"auth_header": auth_header_token,
							"access_time": datetime.now().strftime("%A, %d %B %Y %H:%M:%S"),
							"logging_access_key": self.accessKey,
							"json": json_data,
							"request_params": str(dict(request.args))
						}

						self.startPost(post_data)

					except Exception as e:
						result = func(*args, **kwargs)

						trace = traceback.format_exc()

						kwargs = {
							"trace": trace,
							"exception": str(e)
						}

						post_data = {
							"error": str(e),
							"stack_trace": trace,
							"method": request.method,
							"source_ip": request.remote_addr,
							"url": request.url,
							"status_code": 500,
							"headers": str(header_dict),
							"user_agent": user_agent,
							"language": language,
							"platform": platform,
							"browser": browser,
							"referer": referer,
							"origin": origin,
							"auth_header": auth_header_token,
							"access_time": datetime.now().strftime("%A, %d %B %Y %H:%M:%S"),
							"logging_access_key": self.accessKey,
							"json": json_data,
							"request_params": str(dict(request.args))
						}

						self.startPost(post_data)

					return result

				return execute

			return log_decorator

	def startPost(self, postData):
		loop = asyncio.new_event_loop()
		asyncio.set_event_loop(loop)
		loop.run_until_complete(self.postAsyncData(postData))

	async def postAsyncData(self, postData):
		logging_url = self.app.config["LOGGING_URL"]
		headers = {
			"X-Api-Key": self.app.config["LOG_AUTH_KEY"],
			"Content-Type": "application/json",
			"Origin": request.remote_addr
		}

		async with aiohttp.ClientSession() as session:
			await session.post(logging_url, json=postData, headers=headers)

	def __init__(self, app = None, accessKey = None, config_object = None):
		if not app:
			raise ValueError("'app' must be an instance of a Flask application")

		if not "LOGGING_URL" in app.config:
			raise ValueError("The configuration variable 'LOGGING_URL' must be set.")

		if not "LOG_AUTH_KEY" in app.config:
			raise ValueError("The configuration variable 'LOG_AUTH_KEY' must be set.")

		if not isinstance(app.config["LOGGING_URL"], str):
			raise TypeError("'LOGGING_URL' must be an instance of type 'str'")

		if not isinstance(app.config["LOG_AUTH_KEY"], str):
			raise TypeError("'LOG_AUTH_KEY' must be an instance of type 'str'")

		if not config_object:
			self.pre_request = True
			do_not_log = []

		else:
			allowed_values = ["wrapper", "pre_request"]

			if config_object["LOG_TYPE"].lower() not in allowed_values:
				raise ValueError("The value assigned to the config variable 'LOG_TYPE' is not allowed.")

			if config_object["LOG_TYPE"].lower() == "wrapper":
				self.pre_request = False
			elif config_object["LOG_TYPE"].lower() == "pre_request":
				self.pre_request = True

			if "DO_NOT_LOG" in config_object:
				do_not_log = []
			else:
				do_not_log = config_object["DO_NOT_LOG"]

		self.accessKey = accessKey
		self.app = app
		self.do_not_log = do_not_log


#1. The benefits of using my programs features include the fact that they are very familiar. The new feature, which is the ability to import files, is also intuitive and helpful for orgaanizing work. People like Abi and Pat will find this easy to use, and Tim
#   will see the use of the function and be interested in it.

#2. The cost of using my program is the learning curve, which is low. However, the new feature that I added (file import) may make someone like Abi hesitate to use it as there are some unknowns. There is a tutorial to help mitigate this.

#3. Each button will do exactly what it says, so there is a limited amount of information on the screen at the start. However, as the program is used (ex: using the import function or creating a note) new options are added for the user to interact with. Nothing
#   unnecessary is given to the user, so only the info they wanted is given.

#4. Each button is clearly labeled to make it as familiar as possible, so even people like Abi will feel comfortable in the program. Many of the features are also similar to other popular applications in functionality.

#5. The user is easily able to delete anything they have typed in the program, so people like Abi or Pat can avoid being overwhelmed.

#6. The application starts off with a tutorial that can be hidden. The buttons are also clearly labeled, so people like Abi will have a clear explanation of each of the features. People like Tim and Pat can instantly hide the tutorial and explore on their own.

#7. The application will have nothing except for a tutorial when it opens, so any approach can be taken when using the program. It is fully up to the user to proceed how they want.

#8. The application encourages tinkering mindfully by putting a limit to how many notes can be created. The program also allows you to bring the tutorial up whenever, so you can see what a button does rather than messing with it forever. This can help people like Tim
#   stay on task by giving them the information they want.

#Quality 1. The first quality attribute I focused on was reliability, which I did by making sure everything ran smoothly with no hiccups. Everything loads quickly and I have not been able to make the program slow down. I did this by keeping each individual process simple.

#Quality 2. The second quality attribute I focused on was flexibility, which I did by allowing the program to accept almost any file type.

#Quality 3. The last attribute I focused on was Integrity, which I did by making sure that it was very hard to crash the program. Each button does what it is supposed to, and I have not experienced any crashes in my testing.

import time
from tkinter import *
from tkinter.ttk import *
import sys

window = Tk()
counter = 0
yPlace = 100
warningCheck = False
currentFileInput = ''
fileContent = ''
tutorialHidden = True

#create entry window
inputFile = Entry(window, width = 50)

tutorial = Text(window, height = 5, width = 50, wrap = WORD)

def saveInput(userInput: Entry):
    with open('exampleSave.txt', 'w') as wf:
        wf.write(userInput.get(1.0, "end-1c"))

    wf.close()
    return

#make a new note if there is room
def makeNote():
    global warningCheck
    global counter
    xPlace = 200
    global yPlace
    global fileContent

    #creates input box inside window (this is the note)
    if counter == 0:
        input = Text(window, height = 10, width = 20, wrap = WORD)
        input.place(x = xPlace, y = yPlace)
        input.insert('end', fileContent)

        saveButton = Button(window, text = "Save", command = saveInput(input))
        saveButton.place(x = xPlace + 45, y = yPlace + 165)

        counter += 1

    elif counter < 3:
        input = Text(window, height = 10, width = 20, wrap = WORD)
        xPlace = xPlace + (250 * counter)
        input.place(x = xPlace, y = yPlace)
        input.insert('end', fileContent)

        saveButton = Button(window, text = "Save", command = saveInput(input))
        saveButton.place(x = xPlace + 45, y = yPlace + 165)

        counter += 1

    #update yPlace prior to 4 so that warningCheck works
    elif counter == 3:
        input = Text(window, height = 10, width = 20, wrap = WORD)
        xPlace = xPlace + (250 * counter)
        input.place(x = xPlace, y = yPlace)
        input.insert('end', fileContent)

        saveButton = Button(window, text = "Save", command = saveInput(input))
        saveButton.place(x = xPlace + 45, y = yPlace + 165)

        counter += 1
        yPlace = yPlace + 200

    #make sure it does not overprint the warning
    elif warningCheck == True:
        pass

    #make warning that the max number of notes has been reached
    elif yPlace > 500:
        warning = Label(window, width = 50, text = "You have created the max number of notes!")
        warning.pack()
        warningCheck = True

    #creates a new row of notes
    elif counter == 4:
        counter = 0
        input = Text(window, height = 10, width = 20, wrap = WORD)
        input.place(x = xPlace, y = yPlace)
        input.insert('end', fileContent)

        saveButton = Button(window, text = "Save", command = saveInput(input))
        saveButton.place(x = xPlace + 45, y = yPlace + 165)

        counter += 1

    #clear file content so that the next note created does not have unwanted text
    fileContent = ''

#take and store user input
def acceptInput():
    global currentFileInput
    global fileContent
    global inputFile

    currentFileInput = inputFile.get()

    with open(currentFileInput, 'r') as rf:
        fileContent = rf.readline()

    rf.close()
    makeNote()

#take input from the user for the file name
def importFile():
    global inputFile

    inputFile.place(x = 760, y = 25)

    takeInput = Button(window, text = "Import File", command = acceptInput)
    takeInput.place(x = 875, y = 50)

#hide the tutorial box
def hideTutorial():
    global tutorial
    global tutorialHidden

    if tutorialHidden == False:
        tutorial.place(x = 675, y = 30)
        tutorialHidden = True

    elif tutorialHidden == True:
        tutorial.place_forget()
        tutorialHidden = False

#basic program loop
while True:
    window.geometry('1280x720')
    window.resizable(0, 0)

    #calls makeNote function to create a small note window when clicked
    noteButton = Button(window, text = 'New Note', command = makeNote)
    noteButton.place(x = 800, y = 0)

    importButton = Button(window, text = "Import", command = importFile)
    importButton.place(x = 875, y = 0)

    tutorial.place(x = 675, y = 30)
    tutorial.insert('end', "Use the 'New Note' button to create a note on the page. This will let you type anything! This will also create a save button to save your input in a file. Use the 'Import' button to take the name of a file to place the text of a file in a new note!")

    closeTutorial = Button(window, text = "Toggle Tutorial", command = hideTutorial)
    closeTutorial.place(x = 950, y = 0)

    window.mainloop()

    break


# one vs rest model

# logistic regression for multi-class classification using built-in one-vs-rest
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, n_classes=3, random_state=1)
# define model
model = LogisticRegression(multi_class='ovr')
# fit model
model.fit(X, y)
# make predictions
yhat = model.predict(X)

from sklearn.multiclass import OneVsRestClassifier
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, n_classes=3, random_state=1)
# define model
model = LogisticRegression()
# define the ovr strategy
ovr = OneVsRestClassifier(model)
# fit model
ovr.fit(X, y)
# make predictions
yhat = ovr.predict(X)

# one vs one model

from sklearn.svm import SVC
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, n_classes=3, random_state=1)
# define model
model = SVC(decision_function_shape='ovo')
# fit model
model.fit(X, y)
# make predictions
yhat = model.predict(X)

from sklearn.svm import SVC
from sklearn.multiclass import OneVsOneClassifier
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, n_classes=3, random_state=1)
# define model
model = SVC()
# define ovo strategy
ovo = OneVsOneClassifier(model)
# fit model
ovo.fit(X, y)
# make predictions
yhat = ovo.predict(X)


from django.core.management.base import BaseCommand
import json

# import sys
# sys.path.append('/users')
from users.models import Nodes

# List of JSON files to import
json_files = [
    '/src/json-files/park_locations.json',
     "/src/json-files/park_node_locations",
    "/src/json-files/worship_locations",
    "/src/json-files/museum_art_locations",
    "/src/json-files/library_locations",
    "/src/json-files/walking_node_locations",
    "/src/json-files/community_locations"
]

# file_path = r'C:\Users\corma\COMP47360\ucdSummerProject\src\json-files\museum_art_locations.json'
class Command(BaseCommand):
    help = 'Import JSON file into PostgreSQL'

    def add_arguments(self, parser):
        parser.add_argument('file_path', type=str, help='Path to the JSON file')

    def handle(self, *args, **options):

        file_path = options['file_path']

        # for file_path in json_files:
        with open(file_path) as f:
            data = json.load(f)

        for item in data['data']:
            node = Nodes(
                id_str=item['id'],
                name=item['name'],
                type=item['type'],
                address=item['address'],
                internet_access=item['internet_access'],
                wheelchair_accessible=item['wheelchair_accessible'],
                opening_hours=item['opening_hours'],
                grid_id=item['grid-id'],
                taxi_zone=item['taxi-zone'],
                precinct=item['precinct'],
                b_score=item['b-score'],
                c_score=item['c-score'],
                rating=item['rating'],
                latitude=item['location']['latitude'],
                longitude=item['location']['longitude'],
            )
            node.save()


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 26 13:37:49 2017

@author: escuser

"""

def cut_swave(infile, cutfile, t1, t2):
    #reads in a sac file
    #full path to output file
    #cuts at t1 sec before s arrival and t2 seconds after
    from obspy import read
    import dread
    import datetime
    from obspy.core.utcdatetime import UTCDateTime

    velocity = 3.5 #km/s

    stream = read(infile)
    tr = stream[0]

    origin_hour = tr.stats.sac.nzhour
    origin_min = tr.stats.sac.nzmin
    origin_sec = tr.stats.sac.nzsec
    origin_msec = tr.stats.sac.nzmsec

    trace_starttime = tr.stats.starttime

    origin_time = (origin_hour*60*60 + origin_min*60 + origin_sec + origin_msec/1000.)# in seconds after start of day
    trace_starttime_sec = trace_starttime.hour*60*60 + trace_starttime.minute*60 + trace_starttime.second

    delta =  origin_time - trace_starttime_sec # in sec
#    print(delta)
    origin_time_UTC = trace_starttime + datetime.timedelta(seconds=delta)#convert origin time to UTC

    evlon =  tr.stats.sac.evlo #deg
    evlat =  tr.stats.sac.evla #deg
    evdepth = tr.stats.sac.evdp #km
    stlon = tr.stats.sac.stlo #deg
    stlat = tr.stats.sac.stla #deg
    stdepth = tr.stats.sac.stdp #km

    #find distance between event and station
    dist =  dread.compute_rrup(evlon, evlat, evdepth, stlon, stlat, stdepth) #in km

    s_travel_time = dist/velocity # in sec
#    print(s_travel_time)
    cuttime = origin_time_UTC + datetime.timedelta(seconds = s_travel_time)#add travel time or utc origin time
#    print(cuttime)
    start = cuttime - datetime.timedelta(seconds = t1)
    end = cuttime + datetime.timedelta(seconds = t2)
    start = str(start)
    end = str(end)
#    print(start, end)
#    print(cuttime - datetime.timedelta(seconds = t1),cuttime + datetime.timedelta(seconds = t2))
#    print(tr.slice(cuttime - datetime.timedelta(seconds = t1),cuttime + datetime.timedelta(seconds = t2), nearest_sample=True))
#    cut_trace = tr.slice(cuttime - datetime.timedelta(seconds = t1),cuttime + datetime.timedelta(seconds = t2), nearest_sample=True)#make a new trace by slicing
    cut_trace = tr.slice(UTCDateTime(start), UTCDateTime(end), nearest_sample=True)#make a new trace by slicing
#    print(tr.data)
#    print(cut_trace)
    cut_trace.write(cutfile, format = 'SAC')

def bin_spec(data, frequency, num_bins):
    import numpy as np
#    import matplotlib.pyplot as plt
    #takes in linear frequency and NE velocity spectra (not power!)

    fstart = frequency[0]#1
    if fstart == 0:
        fstart = frequency[1]
    fend = frequency[-1]

    #index array for bins
    c = np.logspace(np.log10(fstart), np.log10(fend), num_bins)
    l = len(c)
    binned_data = np.zeros(num_bins)
    lower = np.zeros(num_bins)
    upper = np.zeros(num_bins)
    #first point
    #mean of first point and index of point with f less than or equal to c(1)
    index = (frequency <= c[1]).argmin()
#    print index
    upper[0] = index
    lower[0] = 0
    binned_data[0] = np.mean(data[0:index])
    #index = (frequency >= c[l-2]).argmax()
    upper[-1] = -1
    index = (frequency >= c[l-2]).argmax()
    lower[-1] = index
    binned_data[l-1] = np.mean(data[index:-1])
    for i in range(1,l-1):
        lb = (frequency >= c[i-1]).argmax()
        if (frequency <= c[i+1]).argmin() == 0:
            ub = -1
        else:
            ub = (frequency <= c[i+1]).argmin()
        lower[i] = lb
        upper[i] = ub
        #add an if statement if lower = upper
        if lb == ub:
            binned_data[i] = data[lb]
        else:
            binned_data[i] = np.mean(data[lb:ub])

    return c, binned_data

def bin_max_err(data, frequency, num_bins):
    import numpy as np
#    import matplotlib.pyplot as plt
    #takes in linear frequency and NE velocity spectra (not power!)

    fstart = frequency[0]#1
    if fstart == 0:
        fstart = frequency[1]
    fend = frequency[-1]

    #index array for bins
    c = np.logspace(np.log10(fstart), np.log10(fend), num_bins)
    l = len(c)
    binned_data = np.zeros(num_bins)
    lower = np.zeros(num_bins)
    upper = np.zeros(num_bins)
    #first point
    #mean of first point and index of point with f less than or equal to c(1)
    index = (frequency <= c[1]).argmin()
#    print index
    upper[0] = index
    lower[0] = 0
    binned_data[0] = np.mean(data[0:index])
    #index = (frequency >= c[l-2]).argmax()
    upper[-1] = -1
    index = (frequency >= c[l-2]).argmax()
    lower[-1] = index
    binned_data[l-1] = np.mean(data[index:-1])
    for i in range(1,l-1):
        lb = (frequency >= c[i-1]).argmax()
        if (frequency <= c[i+1]).argmin() == 0:
            ub = -1
        else:
            ub = (frequency <= c[i+1]).argmin()
        lower[i] = lb
        upper[i] = ub
        #add an if statement if lower = upper
        if lb == ub:
            binned_data[i] = data[lb]
        else:
            binned_data[i] = np.max(data[lb:ub])

    return c, binned_data

def L1norm(record_paths):
    import os.path as path
    import dread
    from obspy import read
    import numpy as np

    N = len(record_paths)
    L1  = np.zeros((N, 50)) #50 bands, number of recordings
    for i in range(N):
    #for the list of records compute L1 norm in each f band
        base = path.basename(record_paths[i])
        print(record_paths[i])
        box = record_paths[i].split('/')[5]
        network, station, channel, loc = base.split('_')[0:4]
        yyyy, month, day, hh, mm, ss = base.split('_')[4:]
        ss = ss.split('.')[0]
        eventid = yyyy + '_' + month + '_' + day + '_' + hh + '_' + mm + '_' + ss

        raw_file = '/Users/escuser/project/boxes/' + box + '/uncorrected/Event_' + eventid + '/' + network + '_' +  station + '_HHN_' + loc + '_' + eventid + '.SAC'
        event_dir =  '/Users/escuser/project/boxes/' + box + '/secondo/'
        station_dir =  '/Users/escuser/project/boxes/' + box + '/secondo/'

        stream = read(raw_file)
        tr = stream[0]

        evlon =  tr.stats.sac.evlo #deg
        evlat =  tr.stats.sac.evla #deg
        evdepth = tr.stats.sac.evdp #km
        stlon = tr.stats.sac.stlo #deg
        stlat = tr.stats.sac.stla #deg
        stdepth = tr.stats.sac.stdp #km

        #find distance between event and station
        dist =  dread.compute_rrup(evlon, evlat, evdepth, stlon, stlat, stdepth) #in km
        #km to cm
        dist = dist*100000
        #record spectra
        record_data = np.genfromtxt(record_paths[i], dtype = float, comments = '#', delimiter = None, usecols = (0,1))#only read in first two cols
        record_spec = record_data[:,1]*dist

        #event spectra
        event_data = np.genfromtxt(event_dir + eventid + '.out', dtype = float, comments = '#', delimiter = None, usecols = (0,1))
        event_spec = event_data[:,1]
        #station spectra
        station_data = np.genfromtxt(station_dir + station + '.out', dtype = float, comments = '#', delimiter = None, usecols = (0,1))
        station_spec = station_data[:,1]

        calc_record_spec = station_spec*event_spec
        residual = (record_spec - calc_record_spec)
        #set recording row equal to residual array
        L1[i:,] = residual
    return L1


import torch
import torchvision.transforms as transforms
from torch.utils.data import Dataset

class PPNetDataset(Dataset):
    def __init__(self, ppg, sbp, dbp, hr):
        self.transform = transforms.Compose([transforms.ToTensor()])
        self.ppg = ppg
        self.sbp = sbp
        self.dbp = dbp
        self.hr = hr

    def __getitem__(self, index):
        if torch.is_tensor(index):
            index = index.tolist()

        ppg = torch.tensor(self.ppg[index], dtype=torch.float32)
        sbp = torch.tensor(self.sbp[index], dtype=torch.float32)
        dbp = torch.tensor(self.dbp[index], dtype=torch.float32)
        hr = torch.tensor(self.hr[index], dtype=torch.float32)

        inputs = ppg.reshape(1,-1)
        targets = torch.stack([sbp,dbp,hr],dim=0)

        if torch.cuda.is_available():
            inputs = inputs.to('cuda')
            targets = targets.to('cuda')

        return inputs, targets

    def __len__(self):
        return len(self.ppg)


import cv2

from pyzbar import pyzbar

def detect_qrcode(frame):

    barcodes = pyzbar.decode(frame)
    qrCodeDetector = cv2.QRCodeDetector()
    decodedText, points, _ = qrCodeDetector.detectAndDecode(frame)
    for barcode in barcodes:
        (x, y, w, h) = barcode.rect
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
        barcodeData = barcode.data.decode("utf-8")
        barcodeType = barcode.type

        text = "{} ({})".format(barcodeData, barcodeType)
        cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
                    0.5, (0, 0, 255), 2)

    cv2.imshow("Image", frame)
    cv2.waitKey()

if __name__ == '__main__':

    img = cv2.imread("/media/mensa/Data/Task/TrolleyDetection/train_data/new_train_data/IMG_20200401_141536.jpg")
    detect_qrcode(frame=img)


import unittest
import bmi_calculator

class BmiTest(unittest.TestCase):

    def test_for_valid_source_record(self):
        test_data = {"Gender": "Male", "HeightCm": "171", "WeightKg": "150" }
        self.assertTrue(bmi_calculator.is_valid_record(test_data))

    def test_for_invalid_source_record(self):
        test_data = {"Gender": "Male", "HeightCm": "171", "WeightKg": "unknown" }
        self.assertFalse(bmi_calculator.is_valid_record(test_data))

    def test_for_bmi_calculation(self):
        test_data = {"Gender": "Male", "HeightCm": "161", "WeightKg": "85" }
        expected_result = {'BMI_categoty': 'Moderately obese', 'BMI_range': 32.79194475521777, 'Health_risk': 'Medium Risk'}
        self.assertEqual(bmi_calculator.calculate_bmi(test_data), expected_result)

    def test_for_get_over_weight_people(self):
        test_data = [
                {'Gender': 'Male', 'HeightCm': '180', 'WeightKg': '77', 'BMI_categoty': 'Normal Weight', 'BMI_range': 23.76543209876543, 'Health_risk': 'Low Risk'},
                {'Gender': 'Female', 'HeightCm': '167', 'WeightKg': '250', 'BMI_categoty': 'Very Severly obese', 'BMI_range': 89.64107712718277, 'Health_risk': 'Very High Risk'}
            ]
        expected_result = [
                {'Gender': 'Female', 'HeightCm': '167', 'WeightKg': '250', 'BMI_categoty': 'Very Severly obese', 'BMI_range': 89.64107712718277, 'Health_risk': 'Very High Risk'}
            ]
        self.assertEqual(bmi_calculator.get_over_weight_people(test_data), expected_result)

    def test_for_exception(self):
        test_data = None
        with self.assertRaises(Exception):
            bmi_calculator.processing_for_bmi_calculation(test_data)

if __name__ == '__main__':
    unittest.main()


"""
Flask Documentation:     http://flask.pocoo.org/docs/
Jinja2 Documentation:    http://jinja.pocoo.org/2/documentation/
Werkzeug Documentation:  http://werkzeug.pocoo.org/documentation/

This file creates your application.
"""

import os
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy

import pandas as pd

import re

from Bio.Seq import Seq
from Bio.Alphabet import generic_dna

app = Flask(__name__)

app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'this_should_be_configured')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'postgres:///anton')

db = SQLAlchemy(app)

class Submission(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    submission_time = db.Column(db.DateTime, server_default=db.func.now())

    suid = db.Column(db.String(100))

    jcvi_g1 = db.Column(db.String)
    jcvi_g2 = db.Column(db.String)
    jcvi_gu = db.Column(db.String)

    ecoli_g1 = db.Column(db.String)
    ecoli_g2 = db.Column(db.String)
    ecoli_gu = db.Column(db.String)

    ec_g1 = db.Column(db.String)
    ec_g2 = db.Column(db.String)

    def __repr__(self):
        return "{} {} {}".format(self.suid, self.submission_time, self.jcvi_g1)

    def genes(self):
        return {
            'JCVI-G1': self.jcvi_g1,
            'JCVI-G2': self.jcvi_g2,
            'JCVI-GU': self.jcvi_gu,
            'ECOLI-G1': self.ecoli_g1,
            'ECOLI-G2': self.ecoli_g2,
            'ECOLI-GU': self.ecoli_gu,
            'EC-G1': self.ec_g1,
            'EC-G2': self.ec_g2
        }

### Load sequence data

jcvi_genes = pd.read_csv('./data/aad6253-Hutchison-SM-database-S1.csv', skiprows=[0])
syn3_genes = pd.concat([jcvi_genes[jcvi_genes['KD_S3'] == 'k'], jcvi_genes[jcvi_genes['KD_S3'] == 'r']])
assignments = pd.read_csv('./data/assignments.csv')

data = assignments.merge(syn3_genes[['Locus', 'ProteinSequence']], left_on='Known Gene 1', right_on='Locus', suffixes=['', '-G1'])
data = data.merge(syn3_genes[['Locus', 'ProteinSequence']], left_on='Known Gene 2', right_on='Locus', suffixes=['', '-G2'])
data = data.merge(syn3_genes[['Locus', 'ProteinSequence']], left_on='Unknown Gene', right_on='Locus', suffixes=['', '-GU'])

def get_student(suid):
    students = data['Email'].str.split('@').str[0].str.match(suid)
    if not students.any() or suid == '':
        return False

    student_genes = data[students]
    name = student_genes['First Name'].iloc[0] + " " + student_genes['Last Name'].iloc[0]
    genes = {
        'JCVI-G1': student_genes['Locus'].iloc[0],
        'JCVI-G2': student_genes['Locus-G2'].iloc[0],
        'JCVI-GU': student_genes['Locus-GU'].iloc[0]
    }

    aas = {
            'JCVI-G1': student_genes['ProteinSequence'].iloc[0],
            'JCVI-G2': student_genes['ProteinSequence-G2'].iloc[0],
            'JCVI-GU': student_genes['ProteinSequence-GU'].iloc[0]
    }

    return name, genes, aas

def validate_gene(dna, aa):
    notes = list()

    # Clean up DNA sequence input
    dna = re.sub('[^A-Z]+', '', dna.strip().upper())

    if dna is None or dna == "":
        return True, []

    if len(dna) % 3 != 0:
        notes.append("Sequence doesn't obey triplet code (length not a multiple of three).")

    if re.search('[^ATGC]', dna):
        notes.append("Sequence contains invalid characters (must be A, T, G, C).")

    if not dna[:3] == "ATG":
        notes.append("No Start")

    try:
        prot = Seq(dna, generic_dna).translate(table=11)
        prot_myco = Seq(dna, generic_dna).translate(table=4)
    except:
        notes.append("Error translating DNA")
        return False, notes

    if len(prot) == 0:
        notes.append("Sequence does not translate to protein.")

    if not (len(prot) > 0 and prot[-1] == "*"):
        notes.append("No stop codon.")
        prot += "*"

    if aa is not None:
        aa = re.sub('[^A-Z]+', '', aa.strip().upper())

        if not prot[:-1] == aa:
            if prot_myco[:-1] == aa:
                notes.append("Not codon-optimized for E. coli.")
            else:
                notes.append("Translated DNA does not match target amino acid sequence.")

    if len(notes) == 0:
        return True, ['DNA meets validation criteria.']

    return False, notes

def validate_genes(genes, aas=dict()):
    dnas = dict()
    okays = dict()
    gene_feedback = dict()

    for gene in ['JCVI-G1', 'JCVI-G2', 'JCVI-GU', 'ECOLI-G1', 'ECOLI-G2', 'ECOLI-GU', 'EC-G1', 'EC-G2']:
        dna = genes[gene]
        if dna is None or dna.strip() == "":
            continue

        aa = None
        if gene in aas:
            aa = aas[gene]

        okay, notes = validate_gene(dna, aa)

        dnas[gene] = dna
        okays[gene] = okay
        if notes:
            gene_feedback[gene] = notes

    return  okays, dnas, gene_feedback

###
# Routing for your application.
###

@app.route('/')
def home():
    """Render website's home page."""
    return render_template('home.html')

@app.route('/dna', methods=['GET'])
def dna():
    """Render the main DNA validation page."""

    suid = request.args.get('suid', '')
    student = get_student(suid)

    if not student:
        flash("Your SUID, {}, is unknown".format(suid), 'danger')
        return redirect(url_for('home'))

    name, genes, aas = student

    okay, dna, feedback = dict(), dict(), dict()

    last_sub = Submission.query.filter_by(suid=suid).order_by(db.desc(Submission.submission_time)).first()
    if last_sub:
        okay, dna, feedback = validate_genes(last_sub.genes(), aas)

    return render_template('dna.html', suid=suid, name=name, genes=genes, okay=okay, dna=dna, feedback=feedback)

@app.route('/dna', methods=['POST'])
def dna_submit():
    suid = request.form['suid']
    student = get_student(suid)

    if not student:
        return redirect(url_for('home'))

    name, genes, aas = student

    sub = Submission()
    sub.suid = suid

    okays, dnas, gene_feedback = validate_genes(request.form, aas)

    for gene, dna in dnas.items():
        setattr(sub, gene.lower().replace("-", "_"), dna)

    db.session.add(sub)
    db.session.commit()

    flash("Your sequences were successfully submitted", "success")
    return render_template('dna.html', suid=suid, name=name, genes=genes, okay=okays, dna=dnas, feedback=gene_feedback)

@app.route('/about/')
def about():
    """Render the website's about page."""
    return render_template('about.html')

###
# The functions below should be applicable to all Flask apps.
###

@app.route('/<file_name>.txt')
def send_text_file(file_name):
    """Send your static text file."""
    file_dot_text = file_name + '.txt'
    return app.send_static_file(file_dot_text)

@app.after_request
def add_header(response):
    """
    Add headers to both force latest IE rendering engine or Chrome Frame,
    and also to cache the rendered page for 10 minutes.
    """
    response.headers['X-UA-Compatible'] = 'IE=Edge,chrome=1'
    # response.headers['Cache-Control'] = 'public, max-age=600'
    return response

@app.errorhandler(404)
def page_not_found(error):
    """Custom 404 page."""
    return render_template('404.html'), 404

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


# 95. 不同的二叉搜索树 II
# 给定一个整数 n，生成所有由 1 ... n 为节点所组成的二叉搜索树。
#
# 示例:
#
# 输入: 3
# 输出:
# [
#   [1,null,3,2],
#   [3,2,null,1],
#   [3,1,null,null,2],
#   [2,1,3],
#   [1,null,2,null,3]
# ]
# 解释:
# 以上的输出对应以下 5 种不同结构的二叉搜索树：
#
#    1         3     3      2      1
#     \       /     /      / \      \
#      3     2     1      1   3      2
#     /     /       \                 \
#    2     1         2                 3

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """
        if n <= 0:
            return []
        res = [None] * (n + 1)
        res[0] = [None]
        for i in range(1, n + 1):
            # 初始化一个列表对象
            res[i] = []
            for j in range(i):
                for left in res[j]:
                    for right in res[i - j - 1]:
                        # 注意：这里是 j + 1 ，表示根结点，画个图就很清楚了
                        root = TreeNode(j + 1)
                        root.left = left
                        # 每个结点都有固定偏移的拷贝
                        root.right = self.__shift_clone(right, j + 1)
                        res[i].append(root)
        return res[n]

    def __shift_clone(self, root, k):
        if root is None:
            return root
        cur_node = TreeNode(root.val + k)
        cur_node.left = self.__shift_clone(root.left, k)
        cur_node.right = self.__shift_clone(root.right, k)
        return cur_node


import matplotlib.pyplot
import numpy
from gensim.models import word2vec
import numpy as np

'''生成长序列串的子序列集，k为kmer长度'''
def k_mergenerator(WaiTingKmer, k):
    result = open("result.txt", mode="w")
    DNA = []
    for i in WaiTingKmer:
        line = []
        for j in range(len(i)-k+1):
            line.append(i[j:j+k])
            result.write(i[j:j+k])
            result.write(" ")
        DNA.append(line)
        result.write("\n")
    return DNA

'''生成整条基因数据的向量，生成方式为将每个kmer向量相加'''
def DNA_to_array(DNA, module):
    DNA_array = []
    sum = 0
    for i in DNA:
        for j in i:
            sum = sum + module.wv[j]
        DNA_array.append(sum)
    return DNA_array

if __name__ == '__main__':
    splice = open("splice.data")
    lable = []
    DNA = []
    for i in splice:
        lable.append(i.split(",")[0])
        DNA.append(i.split(",")[2].replace(" ", "").replace("\n", ""))
    splice.close()
    # 获取Kmer
    DNAkmer = k_mergenerator(DNA, 3)
    # 使用word2vec出基因数据
    genes = word2vec.Text8Corpus("result.txt")
    model = word2vec.Word2Vec(genes, sg=1, min_count=1, vector_size=100)
    print(model)

    model.wv.save_word2vec_format("VectorForGene", binary=False)

    """转化成其他模块能用向量数据"""
    # word_list = model.wv.index_to_key
    # # print(word_list)
    # embeddings = np.array([model.wv[word] for word in word_list])
    # print(embeddings)
    """把DNA文件转化为向量（还是列表）"""
    lable = np.array(lable)
    DNAarray = DNA_to_array(DNAkmer, model)

    '''试试看能不能用kmeans'''
    # # print(npemd)
    # from sklearn.cluster import k_means
    # fuck = k_means(DNAarray,n_clusters=3)
    # result = numpy.array(fuck[1])
    # print(result)
    # fu = []
    # for cluster in range(3):
    #     fu.append(list(lable[np.where(fuck[1] == cluster)]))
    # print("第一类 EI",fu[0].count("EI")," IE ",fu[0].count("IE")," N ",fu[0].count("N"),)
    # print("第二类 EI",fu[1].count("EI")," IE ",fu[1].count("IE")," N ",fu[1].count("N"),)
    # print("第三类 EI",fu[2].count("EI")," IE ",fu[2].count("IE")," N ",fu[2].count("N"),)
    # """kmeans 结果大概78左右"""

    '''试试看能不能svm'''
    DNAarray = np.array(DNAarray)
    print(DNAarray.shape)

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(np.array(DNAarray),np.array(lable),test_size=0.2)
    from sklearn.svm import SVC
    svmclass = SVC(kernel="rbf")
    print(len(X_train),len(y_train))
    svmclass.fit(X_train,y_train)
    res = svmclass.predict(X_test)
    import sklearn.metrics as sm
    bg = sm.classification_report(y_test, res)
    SB = sm.confusion_matrix(y_test,res)
    print(SB)
    sm.ConfusionMatrixDisplay
    # for i in range(len(y_test)):
    #     print(y_test[i],res[i])
    print('分类报告：', bg, sep='\n')