from PyQt4.QtGui import QMainWindow,QListWidgetItem, QMessageBox, QTableWidgetItem, QInputDialog,QLineEdit, QFileDialog
from Ui_MainWindow import Ui_MainWindow
from Gramaticas.Producao import Producao
from Gramaticas.Gramatica import Gramatica, ExcecaoConstruirGramatica
from Automatos.Automato import Automato, ExcecaoMinimizarAutomatoNaoDeterministico
from Expressao.Expressao import Expressao, ExcecaoExpressaoInvalida
import pickle, random

SIMBOLO_SEPARADOR_TRANSICAO = "|"
SIMBOLO_SEPARADOR_PRODUCAO = "->"
DIRETORIO_GRAMATICAS = "persistencia/Gramaticas/"
DIRETORIO_AUTOMATOS = "persistencia/Automatos/"

class MainWindow (QMainWindow, Ui_MainWindow):
    """
    Janela grafica do programa, que chama e configura os metodos
    dos automatos e das gramaticas
    """

    def __init__(self, parent=None):
        '''
        inicializa os dados da gramatica e do automato atuais
        '''
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self._infoGramaticaAtual = {
                                     "ProducaoInicial" : None,
                                     "NaoTerminais" : set([]),
                                     "Terminais" : set([]),
                                     "Producoes" : []
                                     }

        self._infoAutomatoAtual = {
                                    "EstadoInicial" : None,
                                    "EstadosFinais" : set([]),
                                    "Alfabeto" : set([]),
                                    "Estados" : set([]),
                                    "TabelaTransicao" : {}
                                    }

    def adicionarProducao(self):
        '''
        adiciona a producao entrada na caixa de producoes na lista de producao
        apenas se ela for valida
        Gera uma excecao caso a producao nao seja valida
        '''
        try:

            #pega a producao entrada pelo usuario e remove os espacos em branco
            producao = self.caixaProducoes.text().remove(" ")

            #verifica se tem epsilon, caso tenha, tem que estar na producao inicial e nao deve possuir recursao
            if str(producao).count("&") > 0 and (self.listaProducoes.count() > 0 or str(producao).count(str(producao)[0]) >= 2 ):
                raise ExcecaoAdicionarProducao("Producao invalida. So eh permitido & na producao inicial e sem recursao")

            #verifica se a producao atende os padroes das gramaticas regulares
            if self._verificarProducao(producao):
                p = QListWidgetItem(producao)
                self.listaProducoes.addItem(p)
                self.caixaProducoes.setText("")

        except ExcecaoAdicionarProducao as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def deletarProducao(self):
        '''
        Deleta a producao selecionada pelo usuario na lista de producoes ja aceitas
        e remove o alfa dessa producao da lista de nao terminais
        '''
        linha = self.listaProducoes.currentRow()
        item = self.listaProducoes.takeItem(linha)
        nt = self._infoGramaticaAtual["NaoTerminais"]
        self._infoGramaticaAtual["NaoTerminais"] = nt.difference(str(item.text())[0])

    def converterGRparaAF(self):
        """
        Converte a gramatica entrada pelo usuario em um automato finito
        primeiro monta a gramatica pegandos os dados que estao na lista de producao
        depois manda converter e mostrar o automato resultante
        """
        try:
            self._limparAutomatoResultante()
            gramatica = self._montarGramatica()
            if gramatica is not None:
                automato = self._converterGRparaAF(gramatica)
                self._mostrarAutomato(automato)
        except ExcecaoImpossivelMontarGramatica as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def novaGramatica(self):
        """
        Limpa todas as caixas e listas e reinicializa as variaveis para poder
        criar uma nova gramatica
        """
        self._limparListaSentencas()
        self._limparProducoes()
        self._limparCaixasGramatica()
        self._infoGramaticaAtual["NaoTerminais"] = set([])

    def novoAutomato(self):
        """
        Limpa todas as caixas, listas e tabelas e tambem reinicializa
        as variaveis para poder criar um novo automato
        """
        self._infoAutomatoAtual["EstadoInicial"] = None
        self._infoAutomatoAtual["EstadosFinais"] = set([])
        self._infoAutomatoAtual["Alfabeto"] = set([])
        self._infoAutomatoAtual["Estados"] = set([])
        self._infoAutomatoAtual["TabelaTransicao"] = {}
        self._limparAutomatoResultante()
        self._limparEstados()
        self._limparAlfabeto()
        self._limparCaixasAutomato()

    def gerarSentencas(self):
        """
        Gera as sentencas de tamanho n utilizando a gramatica
        passada pelo usuario
        """

        try:
            #pega o valor de n (tamanho da sentenca)
            n = int(self.caixaTamanhoProducoes.text())
            if n <= 0:
                QMessageBox.warning(self,"Erro","Entre com um numero positivo maior que zero.", QMessageBox.Ok)
                return

            #limpa a lista de sentencas anteriores, monta a gramatica e gera as sentencas
            self._limparListaSentencas()
            gramatica = self._montarGramatica()
            sentencas = gramatica.gerarSentencas(n)

            #popula a lista de sentencas
            for sentenca in sentencas:
                self.listaSentencas.addItem( QListWidgetItem(str(sentenca))  )

        except ExcecaoConstruirGramatica:
            QMessageBox.warning(self,"Erro","Impossivel construir a gramatica", QMessageBox.Ok)
        except ValueError:
            QMessageBox.warning(self,"Erro","Entre com um numero positivo maior que zero.", QMessageBox.Ok)

    def adicionarEstado(self):
        """
        Adiciona o estado passado na caixa de estados pelo usuario
        na lista de estados e nos dados do automato
        Apenas insere o estado caso ele seja valido
        """
        estado = str(self.caixaEstado.text())

        #verifica se eh uma letra maiuscula que ainda nao foi utilizada
        if estado != estado.upper() or estado == "":
            QMessageBox.warning(self,"Erro","O estado deve ser uma letra maiuscula.", QMessageBox.Ok)
            return
        if estado in self._infoAutomatoAtual["Estados"]:
            QMessageBox.warning(self,"Erro","Esse estado ja foi inserido.", QMessageBox.Ok)
            return

        estados = self._infoAutomatoAtual["Estados"]
        self._infoAutomatoAtual["Estados"] = estados.union(estado)

        #monta o nome do estado com * e -> para poder colocar na lista de estados e na tabela de transicao
        nomeEstado = estado
        if self.cbFinal.isChecked():
            estadosFinais = self._infoAutomatoAtual["EstadosFinais"]
            self._infoAutomatoAtual["EstadosFinais"] = estadosFinais.union(estado)
            nomeEstado = "*" + nomeEstado

        if self.cbInicial.isChecked():
            estadoInicial = self._infoAutomatoAtual["EstadoInicial"]

            #caso seja um estado inicial, verifica se eh o primeiro inserido, caso nao seja, substitui o anterior
            if estadoInicial != None:
                QMessageBox.warning(self,"Atencao","Estado inicial antigo ("+estadoInicial+") substituido por ("+estado+")!", QMessageBox.Ok)

                #substitui o antigo na tabela de transicao
                for i in range(self.tabelaTransicoes.columnCount()):
                    if str(self.tabelaTransicoes.takeVerticalHeaderItem(i).text()) == "->" + estadoInicial or str(self.tabelaTransicoes.takeVerticalHeaderItem(i).text()) == "->*" + estadoInicial:
                        self.tabelaTransicoes.setVerticalHeaderItem(i,QTableWidgetItem(estadoInicial.replace("->","")))

            self._infoAutomatoAtual["EstadoInicial"] = estado
            nomeEstado = "->" + nomeEstado

        #adiciona na lista de estados e na tabela de transicao
        self.listaEstados.addItem(nomeEstado)
        n = self.tabelaTransicoes.rowCount()
        self.tabelaTransicoes.setRowCount(n+1)
        self.tabelaTransicoes.setVerticalHeaderItem(n,QTableWidgetItem(nomeEstado))
        self.caixaEstado.setText("")
        self.cbFinal.setChecked(False)
        self.cbInicial.setChecked(False)

    def adicionarAlfabeto(self):
        """
        Adiciona um letra do alfabeto entrada pelo usuario na lista de alfabeto
        e nas informacoes do automato atual
        Apenas insere o simbolo na lista do alfabeto caso ele seja valido
        """

        #pega o alfabeto entrado
        alfabeto = str(self.caixaAlfabeto.text())

        #verifica se eh minusculo e se ainda nao foi utilizado
        if alfabeto != alfabeto.lower() or alfabeto == "":
            QMessageBox.warning(self,"Erro","O alfabeto deve ser uma letra minuscula.", QMessageBox.Ok)
            return
        if alfabeto in self._infoAutomatoAtual["Alfabeto"]:
            QMessageBox.warning(self,"Erro","Esse simbolo ja foi inserido.", QMessageBox.Ok)
            return

        #adiciona nas informacoes do automato atual, na tabela de transicao e na lista de alfabetos
        n = self.tabelaTransicoes.columnCount()
        self.tabelaTransicoes.setColumnCount(n+1)
        self.tabelaTransicoes.setHorizontalHeaderItem(n,QTableWidgetItem(alfabeto))
        letras = self._infoAutomatoAtual["Alfabeto"]
        self._infoAutomatoAtual["Alfabeto"] = letras.union(alfabeto)
        self.listaAlfabeto.addItem(alfabeto)
        self.caixaAlfabeto.setText("")

    def deletarEstado(self):
        """
        Deleta o estado selecionado pelo usuario e remove
        as referencias a esse estado das informacoes do
        automato atual
        """

        #pega o estado que o usuario deseja remover
        estado = str(self.listaEstados.currentText())

        #verifica se existe algum estado para remover
        if estado != "":
            indice = self.listaEstados.currentIndex()
            self.listaEstados.removeItem(indice)

            #agora deleta a linha desse estado
            for indice in range(self.tabelaTransicoes.rowCount()):
                if self.tabelaTransicoes.verticalHeaderItem(indice).text() == estado:
                    self.tabelaTransicoes.removeRow(indice)
                    break

            #formata o nome do estado e remove ele das informacoes do automato
            estado = estado.replace('*','')
            estado = estado.replace('->','')
            estados = self._infoAutomatoAtual["Estados"]
            estados.remove(estado)
            self._infoAutomatoAtual["Estados"] = estados

            #caso ele esteja na lista de estados finais, remove
            if estado in self._infoAutomatoAtual["EstadosFinais"]:
                estadosFinais = self._infoAutomatoAtual["EstadosFinais"]
                estadosFinais.discard(estado)
                self._infoAutomatoAtual["EstadosFinais"] = estadosFinais

            #caso ele fosse um estado inicial, remove
            if estado == self._infoAutomatoAtual["EstadoInicial"]:
                self._infoAutomatoAtual["EstadoInicial"] = None

    def deletarAlfabeto(self):
        """
        Retira da lista de alfabeto e das informacoes do automato
        o simbolo selecionado pelo usuario
        """
        #pega o simbolo que o usuario deseja deletar
        alfabeto = str(self.listaAlfabeto.currentText())

        #verifica se esse simbolo realmente existe
        if alfabeto != "":
            indice = self.listaAlfabeto.currentIndex()
            self.listaAlfabeto.removeItem(indice)
            letras = self._infoAutomatoAtual["Alfabeto"]
            letras.remove(alfabeto)
            self._infoAutomatoAtual["Alfabeto"] = letras

            #agora deleta a coluna dessa letra
            for indice in range(self.tabelaTransicoes.columnCount()):

                if self.tabelaTransicoes.horizontalHeaderItem(indice).text() == alfabeto:
                    self.tabelaTransicoes.removeColumn(indice)
                    return

    def determinizarAutomato(self):
        """
        Determiniza o automato especificado
        na tabela de transicoes
        """
        try:
            automato = self._montarAutomato()
            if automato is not None:
                automato.determinizar()
                self._mostrarAutomato(automato)
        except ExcecaoImpossivelMontarAutomato as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def minimizarAutomato(self):
        """
        Minimiza o automato especificado na tabela de transicoes
        caso o automato nao esteja determinizado, a excecao
        gerada eh tratada
        """
        try:
            automato = self._montarAutomato()
            automato.minimizarAFD()
            self._mostrarAutomato(automato)

        except ExcecaoMinimizarAutomatoNaoDeterministico as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)
        except ExcecaoImpossivelMontarAutomato as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def converterERparaAF(self):
        """
        Converte a expressao regular passada pelo usuario em um automato
        deterministico e minimo
        Trata uma excecao caso a gramatica passada seja invalida
        """
        er = str( self.caixaER.text().remove("") )

        expressaoRegular = Expressao()
        try:
            automato = expressaoRegular.converterParaAF(er)
            automato.removerEpsilonTransicao()
            self._mostrarAutomato(automato)
        except ExcecaoExpressaoInvalida as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def salvarAutomato(self):
        """
        Salva o automato caso ele seja valido em um arquivo
        na pasta especificada em DIRETORIO_AUTOMATOS
        tendo por default um nome no formato automato[NumeroQualquer]
        podendo ser alterado por um nome escolhido pelo usuario
        """
        try:
            automato = self._montarAutomato()

            #gera um numero qualquer para montar o nome do automato
            x = int(random.random()*1000)

            #retorna uma tupla (nomeArquivo, true/false)
            nomeArq = QInputDialog.getText(self,"Nome do arquivo", "Qual o nome do automato?", QLineEdit.Normal, "Automato" + str(x))
            if nomeArq[1]:
                pickle.dump(automato, file(DIRETORIO_AUTOMATOS  + str(nomeArq[0]), 'w'))
                QMessageBox.information(self,"Automato salvo","Automato salvo com sucesso!")

        except ExcecaoImpossivelMontarAutomato as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def salvarGramatica(self):
        """
        Salva a gramatica caso ela seja valida em um arquivo
        na pasta especificada em DIRETORIO_GRAMATICAS
        tendo por default um nome no formato gramatica[NumeroQualquer]
        podendo ser alterado por um nome escolhido pelo usuario
        """
        try:
            gramatica = self._montarGramatica()

            #numero qualquer para gerar o nome da gramatica
            x = int(random.random()*1000)

            #retorna uma tupla (nomeArquivo, true/false)
            nomeArq = QInputDialog.getText(self,"Nome do arquivo", "Qual o nome do gramatica?", QLineEdit.Normal, "Gramatica" + str(x))
            if nomeArq[1]:
                pickle.dump(gramatica, file(DIRETORIO_GRAMATICAS  + str(nomeArq[0]), 'w'))
                QMessageBox.information(self,"Gramatica salva","Gramatica salva com sucesso!")

        except ExcecaoImpossivelMontarGramatica as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def carregarAutomato(self):
        """
        Carrega um automato de um arquivo e monta e mostra o
        automato na tabela de transicao
        """
        nomeArquivo = str(QFileDialog.getOpenFileName(self, 'Abrir automato',DIRETORIO_AUTOMATOS,""))
        arq = file(nomeArquivo)
        automato = pickle.load(arq)
        arq.close()
        if automato is not None:
            self._mostrarAutomato(automato)

    def carregarGramatica(self):
        """
        Carrega um arquivo contendo uma gramatica e monta
        e mostra a gramatica na lista de producoes
        """
        nomeArquivo = str(QFileDialog.getOpenFileName(self, 'Abrir gramatica',DIRETORIO_GRAMATICAS,""))
        arq = file(nomeArquivo)
        gramatica = pickle.load(arq)
        arq.close()
        if gramatica is not None:
            self._mostrarGramatica(gramatica)

    def reconhecerSentenca(self):
        """
        Verifica se o automato em questao reconhece uma sentenca especifica ou nao
        """
        try:
            automato = self._montarAutomato()
            sentenca = str(self.caixaSentenca.text())
            reconheceu = automato.reconhecerSentenca(sentenca)
            if reconheceu:
                QMessageBox.information(self,"Reconhecimento","A sentenca " + sentenca + " pertence a linguagem!")
            else:
                QMessageBox.information(self,"Reconhecimento","A sentenca " + sentenca + " nao pertence a linguagem!")

        except ExcecaoImpossivelMontarAutomato as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def converterAFparaGR(self):
        """
        Converte um automato finito que esteja corretamente
        especificado para uma gramatica regular e mostra essa
        gramatica na lista de producoes
        Verifica se o automato esta corretamente especificado
        """
        try:
            self._limparProducoes()
            automato = self._montarAutomato()
            gramatica = self._converterAFparaGR(automato)
            self._mostrarGramatica(gramatica)

        except ExcecaoImpossivelMontarAutomato as mensagem:
            QMessageBox.warning(self,"Erro", str(mensagem), QMessageBox.Ok)

    def _limparAutomatoResultante(self):
        """
        Limpa a tabela de transicao que contem
        o automato resultante
        NAO DELETA as informacoes do automato, apensar apaga
        o automato visualmente
        """
        for _ in range(self.tabelaTransicoes.rowCount()):
            self.tabelaTransicoes.removeRow(0)

        for _ in range(self.tabelaTransicoes.columnCount()):
            self.tabelaTransicoes.removeColumn(0)

    def _atualizarAutomato(self, automato):
        """
        Atualiza as informacoes do automato usando os
        dados do automato passado como paramentro
        """
        self._infoAutomatoAtual["EstadoInicial"] = automato.estadoInicial
        self._infoAutomatoAtual["EstadosFinais"] = automato.estadosFinais
        self._infoAutomatoAtual["Alfabeto"] = automato.alfabeto
        self._infoAutomatoAtual["Estados"] = automato.estados
        self._infoAutomatoAtual["TabelaTransicao"] = automato.tabelaTransicao

    def _atualizarGramatica(self, gramatica):
        """
        Atualiza as informacoes da gramatica usando os
        dados da gramatica passada como paramentro
        """
        self._infoGramaticaAtual["ProducaoInicial"] = gramatica.producaoInicial
        self._infoGramaticaAtual["NaoTerminais"] = gramatica.naoTerminais
        self._infoGramaticaAtual["Terminais"] = gramatica.terminais
        self._infoGramaticaAtual["Producoes"] = gramatica.producoes

    def _mostrarAutomato(self, automato):
        """
        Mostra o automato passado (e ja corretamente especificado)
        na tabela de transicao
        Tambem popula a lista de estados e a lista de simbolos do alfabeto
        """
        #limpandos os dados do automato anterior
        self._limparCaixasAutomato()
        self._limparAlfabeto()
        self._limparEstados()
        self._limparAutomatoResultante()

        self._atualizarAutomato(automato)

        tabelaTransicao = automato.tabelaTransicao

        #pega os simbolos de transicao e ordena
        alfabeto = ([letra for letra in automato.alfabeto])
        alfabeto.sort()

        #popula a lista de simbolos do alfabeto
        for letra in alfabeto:
            n = self.tabelaTransicoes.columnCount()
            self.tabelaTransicoes.setColumnCount(n+1)
            self.tabelaTransicoes.setHorizontalHeaderItem(n,QTableWidgetItem(letra))
            self.listaAlfabeto.addItem(letra)

        #para cada um dos estados do automato
        linha = 0
        n = len(tabelaTransicao.keys())
        self.tabelaTransicoes.setRowCount( n )

        #popula a lista de estados
        for estado in tabelaTransicao.keys():
            transicoes = tabelaTransicao.get(estado)

            if estado == self._infoAutomatoAtual["EstadoInicial"] and estado in self._infoAutomatoAtual["EstadosFinais"]:
                estado = "*->" + estado
            elif estado == self._infoAutomatoAtual["EstadoInicial"]:
                estado = "->" + estado
            elif estado in self._infoAutomatoAtual["EstadosFinais"]:
                estado = "*" + estado

            self.tabelaTransicoes.setVerticalHeaderItem(linha,QTableWidgetItem(estado))
            self.listaEstados.addItem(estado)
            coluna = 0

            for letra in transicoes.keys():
                simbolo = transicoes.get(letra)

                for i in range(len(alfabeto)):
                    if alfabeto[i] == letra:
                        coluna = i
                        self.tabelaTransicoes.setItem(linha,coluna,QTableWidgetItem(simbolo))

            linha += 1

    def _verificarProducao(self, producao):
        """
        Verifica se a producao passada eh valida segundo
        as especificados das gramaticas regulares
        Retorna True ou lanca uma excecao contendo a explicacao
        do porque a producao nao foi aceita
        """
        #valores possiveis de serem usados na producao
        maiusculas = map(chr, range(65, 91))
        minusculas = map(chr, range(97, 123))
        numeros = map(chr, range(48, 57))
        numeros.append("&")

        p = producao.split(SIMBOLO_SEPARADOR_PRODUCAO)

        #se o resultado for maior que 2 (o terminal e suas producoes)
        if len(p) != 2:
            raise ExcecaoAdicionarProducao("Deve haver apenas um simbolo " + SIMBOLO_SEPARADOR_PRODUCAO + " em toda a producao.")
        #se alfa for maior que um ou nao for maiuscula
        if len(p[0]) != 1 or str(p[0]) not in maiusculas:
            raise ExcecaoAdicionarProducao("Producao invalida. Alfa ("+str(p[0])+") deveria ser maiuscula e com apenas um caracter.")
        if str(p[0]) in self._infoGramaticaAtual["NaoTerminais"]:
            raise ExcecaoAdicionarProducao("Esse nao terminal ja foi utlizado, escolha outro")

        transicoes = p[1].split(SIMBOLO_SEPARADOR_TRANSICAO)

        #para cada uma das transicoes encontradas
        for t in transicoes:

            #transicoes no formato aA
            if len(t) == 2:
                #verifica se a primeira eh minuscula e a segunda maiuscula
                if str(t[0]) != str(t[0]).lower() or str(t[1]) != str(t[1]).upper():
                    raise ExcecaoAdicionarProducao("Transicao " + str(t) + " no formato errado. Deveria ser " + str(t[0]).lower() + str(t[1]).upper())
                elif str(t[1]) in numeros:
                    raise ExcecaoAdicionarProducao("Transicao invalida. O segundo simbolo nao pode ser um numero, deve ser uma letra maiuscula.")
                elif str(t[0]) not in numeros and str(t[0]) not in minusculas:
                    raise ExcecaoAdicionarProducao("Simbolo invalido na producao " + str(t) + ". Deve-se usar apenas letras ou numeros.")

            #transicoes no formato a
            elif len(t) == 1:
                #caso a primeira letra nao seja um terminal
                if str(t[0]) != str(t[0]).lower():
                    raise ExcecaoAdicionarProducao("A transicao " + str(t) + " esta no formato errado. Deveria ser " + str(t).lower())
                elif str(t[0]) not in numeros and str(t[0]) not in minusculas:
                    raise ExcecaoAdicionarProducao("Simbolo " + str(t[0]) + " eh invalido. Deve ser uma letra ou numero.")

            #caso nao atenda a nenhum dos formatos das gramaticas regulares
            else:
                #caso tenha mais de dois simbolos, nao pertence a GR
                raise ExcecaoAdicionarProducao("A transicao " + str(t) + " esta no formato errado. Deveria ter no maximo dois simbolos.")

        nt = self._infoGramaticaAtual["NaoTerminais"]
        self._infoGramaticaAtual["NaoTerminais"] = nt.union(str(p[0]))
        return True

    def _limparListaSentencas(self):
        """
        Limpa a lista de sentencas de tamanho n geradas pela gramatica
        """
        for _ in range(self.listaSentencas.count()): self.listaSentencas.takeItem(0)

    def _limparCaixasGramatica(self):
        """
        Limpa a caixa onde o usuario entra com a
        producao que deseja adicionar, e tambem limpa a caixa
        que contem o tamanho das sentencas que ele deseja gerar
        """
        self.caixaProducoes.setText("")
        self.caixaTamanhoProducoes.setText("")

    def _limparCaixasAutomato(self):
        """
        Limpa as caixas do automato: a caixa que o usuario usa para entrar
        com o novo simbolo do alfabeto, para entar com o novo estado que deseja
        adicionar e a caixa onde ele especifica uma sentenca que ele gostaria de saber
        se o automato reconhece ou nao
        """
        self.caixaAlfabeto.setText("")
        self.caixaEstado.setText("")
        self.caixaSentenca.setText("")

    def _limparEstados(self):
        """
        Limpa a lista de estados do automato
        """
        for _ in range(self.listaEstados.count()): self.listaEstados.removeItem(0)

    def _limparAlfabeto(self):
        """
        Limpa a lista de simbolos do alfabeto do automato
        """
        for _ in range(self.listaAlfabeto.count()): self.listaAlfabeto.removeItem(0)

    def _montarGramatica(self):
        """
        Monta a gramatica especificada na lista de producoes e lanca uma excecao
        caso alguma coisa nao esteja corretamente especificada
        Caso de tudo certo, retorna uma Gramatica
        """

        terminais = set([])
        nterminais = set([])
        producoes = []
        nterminaisFaltantes = set([])

        #para cada uma das producoes na lista de producoes:
        for indice in range(self.listaProducoes.count()):
            item = self.listaProducoes.item(indice).text()

            #cria uma nova producao e adiciona na lista de producoes
            p = item.split(SIMBOLO_SEPARADOR_PRODUCAO)
            producao = Producao(str(p[0]),str(p[1]))
            producoes.append(producao)

            #adiciona o alfa na lista de nao terminais ja encontrados
            nterminais.add(str(p[0]))
            nterminaisFaltantes.add(str(p[0])) #desnecessario?

            #agora separa as partes do beta e faz a mesma coisa
            for t in str(p[1]).split(SIMBOLO_SEPARADOR_TRANSICAO):
                if len(str(t)) == 2:
                    terminais.add(str(t[0]))
                    nterminaisFaltantes.add(str(t[1]))
                if len(str(t)) == 1 and str(t) != "&":
                    terminais.add(str(t))

        #depois de montar todas as producoes, verifica se algum simbolo apareceu mas nao possui producao propria
        if nterminaisFaltantes.difference(nterminais) != set([]):
            raise ExcecaoImpossivelMontarGramatica("Gramatica invalida. Alguns nao terminais nao foram especificados: " + str(nterminaisFaltantes.difference(nterminais)) )
        if len(producoes) > 0:
            return Gramatica(producoes[0], nterminais, terminais, producoes)
        else:
            raise ExcecaoImpossivelMontarGramatica("Gramatica vazia")

    def _montarAutomato(self):
        """
        Monta o automato especificado na tabela de transicao
        e lanca uma excecao caso ele nao esteja corretamente
        especificado.
        Caso de tudo certo, retorna um Automato
        """
        tabelaTransicao = {}

        #verifica se o automato possui estado inicial e estados finais
        if self._infoAutomatoAtual["EstadoInicial"] == None:
            raise ExcecaoImpossivelMontarAutomato("O automato nao possui estado inicial.")
        if self._infoAutomatoAtual["EstadosFinais"] == set([]):
            raise ExcecaoImpossivelMontarAutomato(self,"Erro","O automato nao possui estados finais.")

        #para cada uma das linhas da tabela de transicoes
        for linha in range(self.tabelaTransicoes.rowCount()):
            aux = {}

            #para cada uma das colunas da tabela de transicoes
            for coluna in range(self.tabelaTransicoes.columnCount()):

                #pega o simbolo do alfabeto que vai para determinado estado
                simboloAlfabeto = str(self.tabelaTransicoes.horizontalHeaderItem(coluna).text())
                transicao = self.tabelaTransicoes.item(linha,coluna)

                #se nao for uma transicao vazia:
                if transicao != None and transicao.text() != "" :
                    transicao = str(transicao.text())

                    #verifica se o estado foi especificado ou se ele nao esta corretamente formado (por exemplo (AB, ou A,)
                    if (len(transicao) == 1 and transicao not in self._infoAutomatoAtual["Estados"] ) or len(transicao) % 2 == 0:
                        raise ExcecaoImpossivelMontarAutomato("A transicao " + transicao + " nao esta corretamente especificada na tabela.")

                    elif len(transicao) % 2 != 0:
                        for i in transicao:
                            if i != ",":
                                if i not in self._infoAutomatoAtual["Estados"]:
                                    raise ExcecaoImpossivelMontarAutomato("A transicao " + transicao + " nao esta corretamente especificada na tabela.")
                    aux[ simboloAlfabeto ] = transicao
#                else:
#                    transicao = ""
#                aux[ simboloAlfabeto ] = transicao
            estado = str(self.tabelaTransicoes.verticalHeaderItem(linha).text())
            estado = estado.replace("*","")
            estado = estado.replace("->","")
            tabelaTransicao[ estado ] = aux

        return Automato(tabelaTransicao, self._infoAutomatoAtual["Alfabeto"], self._infoAutomatoAtual["Estados"],
                            self._infoAutomatoAtual["EstadoInicial"], self._infoAutomatoAtual["EstadosFinais"])

    def _limparProducoes(self):
        """
        Limpa a lista  que mostra todas as producoes da gramatica
        """
        for _ in range(self.listaProducoes.count()): self.listaProducoes.takeItem(0)

    def _mostrarGramatica(self, gramatica):
        """
        Limpa a lista de producoes, atualiza os dados da gramatica
        com a gramatica passada como parametro e mostra seus dados
        na lista de producoes
        """
        self._limparProducoes()
        self._atualizarGramatica(gramatica)

        #insere todos os outros itens
        for producao in gramatica.producoes:
            if producao != gramatica.producaoInicial:
                self.listaProducoes.insertItem(0,QListWidgetItem(str(producao)) )

        #insere a producao inicial
        self.listaProducoes.insertItem(0, QListWidgetItem(str(gramatica.producaoInicial)) )

    def _converterAFparaGR(self, automato):
        """
        Converte o automato finito passado para uma gramatica regular
        Assume-se que o automato passado esta corretamente especificado
        Retorna uma Gramatica
        """
        producoes = []

        #para cada um dos estados
        for estado in automato.tabelaTransicao.keys():
            transicoes = ""

            #para cada uma das transicoes desse estado
            transicao = automato.tabelaTransicao.get(estado)
            for trans in transicao.keys():

                #caso o caminho de destino seja final, coloca apenas o nao terminal
                if transicao.get(trans) in automato.estadosFinais:
                    transicoes += trans + "|"

                t = automato.tabelaTransicao.get(transicao.get(trans))

                #caso o estado de destino tenha alguma transicao, coloca um caminho pra esse estado
                if len(t.keys()) > 0:
                    transicoes += trans + transicao.get(trans) + "|"

            #caso seja a producao inicial e seja final, coloca o epsilon
            if estado == automato.estadoInicial and estado in automato.estadosFinais:
                transicoes += "&" + "|"

            #se nao for vazia, adiciona na lista de producoes
            if transicoes[:-1] != "":
                producoes.append(Producao(estado,transicoes[:-1]))

        for i in range(len(producoes)):
            producao = producoes[i]
            if producao.obterAlfa() == automato.estadoInicial:
                producaoInicial = producao
                break

        estados = ([p.obterAlfa() for p in producoes ])
        return Gramatica(producaoInicial,estados,automato.alfabeto,producoes)

    def _converterGRparaAF(self,gramatica):
        """
        Converte a gramatica regular passada para automato finito
        Assume-se que a gramatica passada esta corretamente especificada
        Retorna um Automato
        """
        estadosFinais = []
        if "F" not in gramatica.naoTerminais:
            estadoFinal = "F"
        else:
            possiveisNaoTerminais = map(chr, range(65, 91))
            for nt in possiveisNaoTerminais:
                if nt not in gramatica.naoTerminais:
                    estadoFinal = nt
                    break

        tabelaTransicao = {}

        for beta in gramatica.producaoInicial.obterListaBetas():
            if beta == "&":
                estadosFinais.append(gramatica.producaoInicial.obterAlfa())

        #para cada uma das producoes
        for producao in gramatica.producoes:

            novaTransicao = {}

            #para cada um dos betas dessa producao
            for beta in producao.obterListaBetas():

                #caso beta seja apenas um terminal
                if len(beta) == 1 and beta != "&":

                    if novaTransicao.has_key(beta):
                        novaTransicao[beta] = novaTransicao[beta] + "," + estadoFinal
                    else:
                        novaTransicao[beta] = estadoFinal

                elif len(beta) == 2:
                    if novaTransicao.has_key(beta[0]):
                        novaTransicao[beta[0]] = beta[1] +","+ novaTransicao[beta[0]]
                    else:
                        novaTransicao[beta[0]] = beta[1]

                alfa = producao.obterAlfa()
                tabelaTransicao[alfa] = novaTransicao

        tabelaTransicao[estadoFinal] = {}
        estadosFinais.append(estadoFinal)
        return Automato( tabelaTransicao, gramatica.terminais, tabelaTransicao.keys(), gramatica.producaoInicial.obterAlfa(), estadosFinais)

#----------------------- classes de Excecao -----------------------

class ExcecaoAdicionarProducao(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr("Producao invalida. " + self.value)

class ExcecaoImpossivelMontarAutomato(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr("Impossivel montar o automato. " + self.value)

class ExcecaoImpossivelMontarGramatica(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr("Impossivel montar a gramatica. " + self.value)


from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import tree
import pydotplus

iris = load_iris()
iris_X = iris.data
iris_Y = iris.target
X_train, X_test, y_train, y_test = train_test_split(
    iris_X, iris_Y, test_size=0.3)

clf = tree.DecisionTreeClassifier()
clf.fit(X_train, y_train)
dot_data = tree.export_graphviz(clf, out_file=None)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("iris.pdf")


import asyncio
import datetime
import os

import discord

from new_skyline2 import SKYLINE

token = os.environ['token']
loop = asyncio.get_event_loop()
client = SKYLINE(loop=loop, intents=discord.Intents.all())

async def main():
    now = datetime.datetime.utcnow()
    endtime = now.replace(hour=17, minute=1, second=0, microsecond=0)
    if now >= endtime:
        endtime += datetime.timedelta(days=1)
    await asyncio.wait([client.start(token)], timeout=(endtime - now).total_seconds())
    await client.close()
    all_tasks = [t for t in asyncio.all_tasks(loop=loop) if t != main_task]
    while all_tasks:
        done, pending = await asyncio.wait(all_tasks, timeout=5)
        print(pending)
        [t.cancel() for t in pending]
        if not pending:
            break

main_task = loop.create_task(main())
loop.run_until_complete(main_task)
loop.close()


#!/usr/bin/env python3

import click
import sys
from pathlib import Path
from RecBlast.RecBlast import RecSearch
import RecBlast.WarningsExceptions as RBWE

def deduce_searchtype(query_type, db_type, search_algorithm):
    # a bit of cleaning
    query_type = query_type.lower()
    db_type = db_type.lower()
    search_algorithm = search_algorithm.lower()

    if "blast" in search_algorithm:
        if query_type == "dna":
            if db_type == "prot":
                return "blastx"
            elif db_type == "dna":
                return "blastn"
            else:
                raise Exception("Unknown search database type! Allowed options are 'dna' or 'prot'")
        elif query_type == "prot":
            if db_type == "prot":
                return "blastp"
            elif db_type == "dna":
                return "tblastn"
            else:
                raise Exception("Unknown search database type! Allowed options are 'dna' or 'prot'")
        else:
                raise Exception("Unknown search sequence type! Allowed options are 'dna' or 'prot'")
    if "blat" in search_algorithm:
        if query_type == "dna":
            if db_type == "prot":
                return "blatx"
            elif db_type == "dna":
                return "blat"
            else:
                raise Exception("Unknown search database type! Allowed options are 'dna' or 'prot'")
        elif query_type == "prot":
            if db_type == "prot":
                return "blatp"
            elif db_type == "dna":
                return "tblat"
            else:
                raise Exception("Unknown search database type! Allowed options are 'dna' or 'prot'")
        else:
                raise Exception("Unknown search sequence type! Allowed options are 'dna' or 'prot'")
    else:
        raise RBWE.SearchEngineNotImplementedError("This search engine hasn't been implemented yet! Only BLAT and BLAST have been implemented!")

@click.command()
@click.option("-q", "--query-file", type=click.Path(exists=True))
@click.option("--query-file-type", type=str, default="fasta")
@click.option("-p", "--max-processes", type=int, default=40)
@click.option("-fp", "--forward-port")
@click.option("-rp", "--reverse-port")
@click.option("-fs", "--forward-species", type=str)
@click.option("-ft", "--forward-twobit", type=click.Path(exists=False))
@click.option("-rs", "--reverse-species", type=str)
@click.option("-rt", "--reverse-twobit", type=click.Path(exists=False))
@click.option("-ps", "--perc-score", type=str, default= "0.1")
@click.option("-pi", "--perc-identity", type=str, default = "0.5")
@click.option("-pq", "--perc-query-span", type=str, default = "0.5")
@click.option("--query_type", type=str, default = "prot")
@click.option("--reverse_type", type=str, default = "dna")
@click.option("--forward_algo", type=str, default = "blat")
@click.option("--reverse_algo", type=str, default = "blat")
@click.option("--reverse_db_type", type=str, default = "dna")
@click.option("--forward_db_type", type=str, default = "dna")
@click.option("--annotation_lookup_tsv", type=str, default = "")
@click.option("--output-root", type=str, default="./output")
@click.option('-v', '--verbose', count=True)
def __main__(query_file, forward_port, forward_species, forward_twobit,
             reverse_port, reverse_species, reverse_twobit,
             query_type, forward_db_type, forward_algo,
             reverse_type, reverse_db_type, reverse_algo,
             perc_score, perc_identity, perc_query_span, query_file_type, max_processes,
             annotation_lookup_tsv, output_root, verbose):
    perc_score = float(perc_score)
    perc_identity = float(perc_identity)
    perc_query_span = float(perc_query_span)

    forward_twobit = Path(forward_twobit)
    reverse_twobit = Path(reverse_twobit)

    print(forward_twobit, reverse_twobit, output_root, perc_identity, perc_score, perc_query_span, query_file, sep="\n", file=sys.stderr)
    output_location = Path(output_root, forward_twobit.stem)
    print(output_location, file=sys.stderr)

    f_search_type = deduce_searchtype(query_type, forward_db_type, forward_algo)
    r_search_type = deduce_searchtype(reverse_type, reverse_db_type, reverse_algo)

    recblast = RecSearch(target_species=forward_species, query_species=reverse_species,
                         forward_search_type=f_search_type, reverse_search_type=r_search_type,
                         sequence_source="twobit", verbose=verbose)
    recblast.max_processes = max_processes
    recblast.set_queries(query_file,
                         infile_type=query_file_type)
    recblast.forward_search_settings['database_port'] = {forward_species: forward_port}
    recblast.forward_search_settings['database'] = {forward_species: str(forward_twobit.name)}
    recblast.forward_search_settings['database_path'] = str(forward_twobit.parent)
    recblast.forward_search_criteria = dict(perc_score=perc_score,
                                            perc_ident=perc_identity,
                                            perc_query_span=perc_query_span)
    recblast.sequence_source_settings['database'] = {forward_species: str(forward_twobit.name)}
    recblast.sequence_source_settings['database_path'] = str(forward_twobit.parent)
    recblast.memory_saver_level = 1
    recblast.reverse_search_settings['database'] = {reverse_species: str(reverse_twobit.name)}
    recblast.reverse_search_settings['database_path'] = str(reverse_twobit.parent)
    recblast.reverse_search_settings['database_port'] = {reverse_species: reverse_port}
    if annotation_lookup_tsv:
        recblast.set_translation_annotation_parameters(method="table", key_value_order=False,
                                                    tsv_location=annotation_lookup_tsv)
    else:
        recblast.set_translation_annotation_parameters(method=False)
    recblast(run_name="{0}-pcScore{1}_pcIdent{2}_pcQuerySpan{3}_reverse-{4}".format(Path(query_file).stem,
                                                                                perc_score,
                                                                                perc_identity,
                                                                                perc_query_span,
                                                                                reverse_twobit.stem),
             output_type="bed-complete",
             output_location=output_location)

if __name__ == "__main__":
    __main__()

exit()


class Solution:
    def findAndReplacePattern(self, words: List[str], pattern: str) -> List[str]:
        def matches_pattern(word, pattern):
            mapping1 = dict()
            mapping2 = dict()

            for i in range(len(word)):
                if word[i] not in mapping1:
                    mapping1[word[i]] = pattern[i]
                else:
                    if mapping1[word[i]] != pattern[i]:
                        return False
                if pattern[i] not in mapping2:
                    mapping2[pattern[i]] = word[i]
                else:
                    if mapping2[pattern[i]] != word[i]:
                        return False
            return True

        answer = []

        for word in words:
            if matches_pattern(word, pattern):
                answer.append(word)
        return answer


import os, sys, re, string
sys.path.append('../../framework')
import bldutil

progs = 'fftwave1dd cfftwave1dd cfftwave1in fftwave2p fftwave3p cfftwave2 cfftwave3 cfftexpmig2 fftexp0test fd2d cfftexp2 cfftexp2test fdtacc wcfftexp2 wcfftexp2adj cfftwave2nsps cfftwave2mix2 wavemixop lrosrtm2 lroslsrtm2 stack2d cstack2d fftexp0test lrlsrtm2mpi imagsrc zolsrtm2 initwave2 correctwave2 lrwave2 cmatrix cfftwave1d zortmgmres claplac psp pspmig premig cfftwave2omp cfftwave3p lrtti2de clfd1 clfd2 ofd2_test swnorm pspp '

# cfftwave2taper fftwave2taper
# cfftwave2taper
# pawave2 cpawave2 cpswave2
# cfftwave2dhalfft
# icfftwave2 cfftwave1dtest cfftwave2test
# cfftwave1dinit cfftwave2nspstest
# lriso2de lrelasiso
# cfftwave2tt lasthope cfftwave2one waveadjtest cfftwave2abc fftwave2abc
# pawave2 cpawave2 cpswave2 icfftwave2 cfftwave1dtest

libprop = 'fftwave2omp fftwave3omp eweks3d vweks3d xcor2 xcor3 xcor3d mutter3'

ccprogs = 'tilr2 ortholr3 cortholr3 cisolr2 cisolr2rev cisolr3 ctilr2 cisolr2grad cisolr2abc cisolr2abc1 cisolr1 canisolr2 canisolr2abc fraclr2 zfraclr2 fraclr2test tilrzone ortholrzone zortholr3 zanisolr2 zanisolr2abc clfdc1 clfdc2 clfdc1-bak zisolr2abc clfdc1frac'

# abclr2 isolr2sta isolr2abc  cfraclr2
# eiktest eiktest2 cisolr1eik eiksol cfraclr2 rfraclr2 cisolr2twostep
# cisolr2hyb icisolr2

mpi_progs = 'mpilsrtm mpiewertm mpirtmop mpilsrtmgmres mpircvrtm mpiqrtm'
#mpiwave2 mpiwave3 mpifftexp1 mpiwave2kiss mpiwave3kiss mpifftexp1kiss'

pyprogs = 'fft'
pymods = ''

try:  # distributed version
    Import('env root pkgdir bindir libdir incdir')
    env = env.Clone()
except: # local version
    env = bldutil.Debug()
    root = None
    SConscript('../lexing/SConstruct')

src = Glob('[a-z]*.c')

env.Prepend(CPPPATH=['../../include'],
            LIBPATH=['../../lib'],
            LIBS=[env.get('DYNLIB','')+'rsf'])

fftw = env.get('FFTW')
if fftw:
    env.Prepend(CPPDEFINES=['SF_HAS_FFTW'])

for source in src:
    inc = env.RSF_Include(source,prefix='')
    obj = env.StaticObject(source)
    env.Depends(obj,inc)

mpicc = env.get('MPICC')
mpi_src = Glob('N[a-z]*.c')
for source in mpi_src:
    inc = env.RSF_Include(source,prefix='')
    obj = env.StaticObject(source,CC=mpicc)
    env.Depends(obj,inc)

mains = Split(progs+' '+libprop)
for prog in mains:
    sources = ['M' + prog]
    bldutil.depends(env,sources,'M'+prog)
    prog = env.Program(prog,map(lambda x: x + '.c',sources))
    if root:
        env.Install(bindir,prog)

mpi_mains = Split(mpi_progs)
#env.Append(LIBS=['fftw3f_mpi'])
for prog in mpi_mains:
    sources = ['M' + prog]
    bldutil.depends(env,sources,'M'+prog)
    if mpicc:
        env.StaticObject('M'+prog+'.c',CC=mpicc)
        #prog = env.Program(prog,map(lambda x: x + '.o',sources),CC=mpicc,LIBS=env.get('LIBS')+['fftw3f_mpi'])
        prog = env.Program(prog,map(lambda x: x + '.o',sources),CC=mpicc)
    else:
        prog = env.RSF_Place('sf'+prog,None,var='MPICC',package='mpi')
    if root:
        env.Install(bindir,prog)

if 'c++' in env.get('API',[]):
    lapack = env.get('LAPACK')
else:
    lapack = None

if lapack:
    libsxx = [env.get('DYNLIB','')+'rsf++','vecmatop']
    if not isinstance(lapack,bool):
        libsxx.extend(lapack)
    env.Prepend(LIBS=libsxx)

ccmains = Split(ccprogs)
for prog in ccmains:
    sources = ['M' + prog]
    if lapack:
        prog = env.Program(prog,map(lambda x: x + '.cc',sources))
    else:
        prog = env.RSF_Place('sf'+prog,None,var='LAPACK',package='lapack')
    if root:
        env.Install(bindir,prog)

for prog in Split('cmatmult2'):
    sources = ['Test' + prog,prog]
    if prog=='cmatmult2':
        sources.append('cgmres')
    bldutil.depends(env,sources,prog)
    sources = map(lambda x: x + '.o',sources)
    env.Object('Test' + prog + '.c')
    env.Program(sources,PROGPREFIX='',PROGSUFFIX='.x')

######################################################################
# SELF-DOCUMENTATION
######################################################################

if root:
    user = os.path.basename(os.getcwd())
    main = 'sf%s.py' % user

    docs = map(lambda prog: env.Doc(prog,'M' + prog),mains+mpi_mains) +  \
           map(lambda prog: env.Doc(prog,'M%s.cc' % prog,lang='c++'),ccmains)
    env.Depends(docs,'#/framework/rsf/doc.py')
    doc = env.RSF_Docmerge(main,docs)
    env.Install(pkgdir,doc)


import json
import logging
logging.basicConfig(level=logging.DEBUG)
import argparse
import uuid

import emission.storage.decorations.user_queries as esdu
import emission.net.ext_service.push.notify_usage as pnu
import emission.net.ext_service.push.query.dispatch as pqd
import emission.core.wrapper.user as ecwu
import emission.core.get_database as edb

def get_uuid_list_for_platform(platform):
    query_fn = pqd.get_query_fn("platform")
    return query_fn({"platform": platform})

def get_upgrade_push_spec(platform):
    android_url = "https://play.google.com/store/apps/details?id=gov.nrel.cims.openpath"
    ios_url = "https://apps.apple.com/us/app/nrel-openpath/id1628058068"
    if platform == "android":
        platform_url = android_url
    elif platform == "ios":
        platform_url = ios_url
    else:
        raise InvalidArgumentException("Found unknown platform %s, expected 'android' or 'ios'" % platform)
    push_spec = {
        "alert_type": "website",
        "title": "Your version of the NREL OpenPATH app may have errors",
        "message": "Please upgrade to the most recent version",
        "image": "icon",
        "spec": {
            "url": platform_url
        }
    }
    return push_spec

def needs_version_update(uuid, target_version):
    curr_profile = edb.get_profile_db().find_one({"user_id": uuid})
    logging.debug("Read profile %s for user %s" % (curr_profile, uuid))
    if curr_profile is None:
        logging.error("Could not find profile for %s" % uuid)
        return False
    elif curr_profile["client_app_version"] == target_version:
        logging.debug("%s is already at version %s" % (uuid, curr_profile["client_app_version"]))
        return False
    else:
        logging.debug("%s is at version %s, needs update to %s" % (uuid, curr_profile["client_app_version"], target_version))
        return True

def push_upgrade_message_for_platform(platform, cli_args):
    logging.info("About to push to %s" % platform)
    uuid_list = get_uuid_list_for_platform(platform)
    logging.info("UUID list for %s = %s" % (platform, uuid_list))
    if cli_args.target_version:
        filtered_uuid_list = [uuid for uuid in uuid_list if needs_version_update(uuid, cli_args.target_version)]
        logging.info("After filtering for %s, uuid_list is %s" % (cli_args.target_version, filtered_uuid_list))
    else:
        filtered_uuid_list = uuid_list
        logging.info("No target version specified, not filtering list")

    spec = get_upgrade_push_spec(platform)
    if cli_args.dry_run:
        logging.info("dry run, skipping actual push")
    else:
        response = pnu.send_visible_notification_to_users(filtered_uuid_list,
                                                            spec["title"],
                                                            spec["message"],
                                                            spec,
                                                            dev = cli_args.dev)
        pnu.display_response(response)

def runTests():
    try:
        edb.get_profile_db().insert_one({"user_id": "v4", "client_app_version": "1.0.4"})
        edb.get_profile_db().insert_one({"user_id": "v5", "client_app_version": "1.0.5"})
        edb.get_profile_db().insert_one({"user_id": "v6", "client_app_version": "1.0.6"})
        assert needs_version_update("v4", "1.0.6")
        assert needs_version_update("v5", "1.0.6")
        assert not needs_version_update("v6", "1.0.6")
        assert not needs_version_update("unknown", "1.0.6")
    finally:
        logging.debug("About to delete all entries from the profile")
        edb.get_profile_db().delete_many({"user_id": "v4"})
        edb.get_profile_db().delete_many({"user_id": "v5"})
        edb.get_profile_db().delete_many({"user_id": "v6"})

if __name__ == '__main__':
    parser = argparse.ArgumentParser(prog="prompt_upgrade_to_latest")

    # until we figure out a way to add unit tests for scripts
    parser.add_argument("--test", action="store_true", default=False,
        help="Do everything except actually push the survey")
    parser.add_argument("-n", "--dry-run", action="store_true", default=False,
        help="Do everything except actually push the survey")
    parser.add_argument("-t", "--target-version",
        help="Only push to people who have not upgraded to this version")
    parser.add_argument("-d", "--dev", action="store_true", default=False)

    args = parser.parse_args()

    if args.test:
        runTests()
    else:
        push_upgrade_message_for_platform("android", args)
        push_upgrade_message_for_platform("ios", args)


"""clean up unused tables

Create Date: 2022-05-02 17:19:09.910095

"""
from alembic import op

# revision identifiers, used by Alembic.
revision = "20220502_171903"
down_revision = "20220425_225456"
branch_labels = None
depends_on = None

def upgrade():
    op.drop_table("region_types", schema="aspen")
    op.drop_table("align_read_workflows", schema="aspen")
    op.drop_table("call_consensus_workflows", schema="aspen")
    op.drop_table("sequencing_reads_collections", schema="aspen")
    op.drop_table("sequencing_instrument_types", schema="aspen")
    op.drop_table("filter_read_workflows", schema="aspen")
    op.drop_table("host_filtered_sequencing_reads_collections", schema="aspen")
    op.drop_table("sequencing_protocol_types", schema="aspen")
    op.drop_table("bams", schema="aspen")
    op.drop_table("called_pathogen_genomes", schema="aspen")

    # Drop dummy data tied to our enums, relevant for dev environments
    op.execute(
        "DELETE FROM aspen.entities WHERE entity_type IN ('SEQUENCING_READS', 'BAM', 'CALLED_PATHOGEN_GENOME', 'HOST_FILTERED_SEQUENCE_READS')"
    )

    op.enum_delete(
        "entity_types",
        [
            "CALLED_PATHOGEN_GENOME",
            "BAM",
            "SEQUENCING_READS",
            "HOST_FILTERED_SEQUENCE_READS",
        ],
        schema="aspen",
    )
    op.enum_delete(
        "workflow_types",
        ["CALL_CONSENSUS", "ALIGN_READ", "FILTER_READ"],
        schema="aspen",
    )

def downgrade():
    raise NotImplementedError("don't downgrade")


import pandas as pd
import tekore as tk
from config import CLIENT_ID, CLIENT_SECRET

class SpotifyData:

    def get_one_song_data(self, query):
        token = tk.request_client_token(CLIENT_ID, CLIENT_SECRET)
        spotify = tk.Spotify(token)
        searched_track = spotify.search(query, types=('track',), market='pl')
        artist_id = searched_track[0].items[0].artists[0].id
        id = searched_track[0].items[0].id
        af = spotify.track_audio_features(id)
        output = [
            [af.danceability,
             af.energy,
             af.loudness,
             af.acousticness,
             af.instrumentalness,
             af.liveness,
             af.speechiness,
             af.valence]
        ]
        print("Znaleziono:", searched_track[0].items[0].artists[0].name, "-", searched_track[0].items[0].name)
        print("Gatunek:", spotify.artist(artist_id).genres[0])
        return pd.DataFrame(output, columns=['danceability', 'energy', 'loudness', 'acousticness', 'instrumentalness',
                                             'liveness', 'speechiness', 'valence'])

    def get_data(self, genres):
        genres_names = genres
        token = tk.request_client_token(CLIENT_ID, CLIENT_SECRET)
        spotify = tk.Spotify(token)
        output = pd.DataFrame(
            columns=['genre', 'danceability', 'energy', 'loudness', 'acousticness', 'instrumentalness',
                     'liveness', 'speechiness', 'valence'])
        for genre in genres_names:
            print('now: ', genre)
            tracks_id = []
            tracks_af = []

            try:
                searched_playlists = spotify.search(genre, types=('playlist',), market='pl', limit=50, offset=0)
                playlist_id = None
                for i in range(100):
                    if searched_playlists[0].items[i].tracks.total >= 100:
                        playlist_id = searched_playlists[0].items[i].id
                        break
                    elif i == 100:
                        playlist_id = searched_playlists[0].items[0].id

                playlist = spotify.playlist(playlist_id)
                playlist_tracks = playlist.tracks.items

                for i in range(100):
                    tracks_id.append(playlist_tracks[i].track.id)

                afs = spotify.tracks_audio_features(track_ids=tracks_id)
                print(len(afs))
                for af in afs:
                    tracks_af.append(
                        [genre, af.danceability, af.energy, af.loudness, af.acousticness, af.instrumentalness,
                         af.liveness,
                         af.speechiness, af.valence])
                x = pd.DataFrame(tracks_af,
                                 columns=['genre', 'danceability', 'energy', 'loudness', 'acousticness',
                                          'instrumentalness',
                                          'liveness', 'speechiness', 'valence'])
                output = pd.concat([output, x])
            except AttributeError:
                print('tekore attribute error')
                continue
            except IndexError:
                print('playlist index error')
                continue
            except TypeError:
                print('audio features type error')
                continue

        return output


import sqlite3

connection = sqlite3.connect('databasePeças.db')
c = connection.cursor()

def CREATE():
    # PEÇA #
    c.execute('CREATE TABLE IF NOT EXISTS PECA (\
        `codigo` VARCHAR(5) NOT NULL,\
        `nomeSingular` VARCHAR(25) NOT NULL,\
        `nomePlural` VARCHAR(25) NOT NULL,\
        `genero` VARCHAR(1) NOT NULL,\
        `preco` VARCHAR(8),\
        PRIMARY KEY(`codigo`));')
    connection.commit()
    connection.close()
CREATE()

Scripts Banco de Dados/criar_database_Peça.py


from codecs import open
from os import path
import re
from setuptools import setup, find_packages

dot = path.abspath(path.dirname(__file__))

# get the dependencies and installs
with open(path.join(dot, 'requirements.txt'), encoding='utf-8') as f:
    all_reqs = f.read().split('\n')

install_requires = [x.strip() for x in all_reqs if 'git+' not in x]
dependency_links = [x.strip().replace('git+', '') for x in all_reqs if
                    x.startswith('git+')]

# parse the version file
ver_content = open("cloudy/_version.py", "rt").read()
ver_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", ver_content, re.M)
if ver_match:
    version = ver_match.group(1)
else:
    raise RuntimeError("Unable to find version string")

setup(
    name='cloudy',
    version=version,
    description='opinionated & personal screenshot handler',
    long_description=(
        'Watches a directory for file changes, uploads them to a remote,'
        'generates a link, shortens it and dumps it into the clipboard.'
    ),
    license='BSD',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Programming Language :: Python :: 3',
    ],
    entry_points={
        'console_scripts': ['cloudy=cloudy.cloudy:cli'],
    },
    keywords='',
    packages=find_packages(exclude=['docs', 'tests*']),
    include_package_data=True,
    install_requires=install_requires,
    dependency_links=dependency_links,
)


import numpy as np
import json

def dump_to_file(arrays, filename):
  arrays_for_dump = {}
  for key, array in arrays.items():
    if isinstance(array, np.ndarray):
      arrays_for_dump[key] = array.tolist()
    else:
      arrays_for_dump[key] = array
      if isinstance(array, dict):
        try:
          for k,v in array.items():
            arrays_for_dump[key][k] = v.tolist()
        except:
          pass
  with open(filename, 'w') as handle:
    json.dump(arrays_for_dump, handle, indent=2)

def load_from_file(filename):
  with open(filename, 'r') as handle:
    arrays_for_dump = json.load(handle)
  arrays = {}
  for key, array in arrays_for_dump.items():
    if isinstance(array, list):
      arrays[key] = np.asarray(array)
    elif isinstance(array, dict):
      try:
        arrays[key] = {int(k):np.asarray(v) for k,v in array.items()}
      except:
        arrays[key] = array
    else:
      arrays[key] = array
  return arrays


from image import PGMImage
import random
from gaussian import convolve

def apply_median_filter(image_pixels, filter_size):
    offset = filter_size // 2
    output = [[0] * len(row) for row in image_pixels]

    for i in range(offset, len(image_pixels) - offset):
        for j in range(offset, len(image_pixels[0]) - offset):
            values = []
            for x in range(-offset, offset + 1):
                for y in range(-offset, offset + 1):
                    values.append(image_pixels[i + x][j + y])
            output[i][j] = sorted(values)[len(values) // 2]

    return output

def salt_and_pepper_noise(image_pixels, percentage):
    output = [row[:] for row in image_pixels]
    num_changes = int(percentage * len(image_pixels) * len(image_pixels[0]) / 100)

    for _ in range(num_changes):
        i, j = random.randint(0, len(image_pixels) - 1), random.randint(0, len(image_pixels[0]) - 1)
        output[i][j] = 0 if random.random() < 0.5 else 255

    return output

def apply_averaging(image_pixels, filter_size):
    filter_vals = [[1/filter_size**2 for _ in range(filter_size)] for _ in range(filter_size)]
    return convolve(image_pixels, filter_vals)


# pylint: disable=W0613
from flask import request
from injector import inject

from app import app
from app.regali_app.list.application.use_cases import (
    get_gift_list,
    get_gift_lists,
    delete_gift_list,
    create_gift_list,
    delete_gift_list_element,
    create_gift_list_element
)
from app.regali_app.shared.infrastructure.routes.authentication import token_required

@inject
@app.route('/giftlists', methods=['POST'])
@token_required
def post_giftlist(
    current_user,
    use_case: create_gift_list.UseCase,
    request_data_transformer: create_gift_list.RequestDataTransformer
):
    return use_case.execute(
        request_data_transformer.transform(
            current_user.id,
            request
        )
    )

@inject
@app.route('/giftlists/<reference>', methods=['GET'])
@token_required
def get_giftlist(current_user, use_case: get_gift_list.UseCase, reference):
    giftlists = use_case.execute(get_gift_list.Request(reference))

    return giftlists

@inject
@app.route('/giftlists', methods=['GET'])
@token_required
def get_giftlists(current_user, use_case: get_gift_lists.UseCase):
    giftlists = use_case.execute()

    return giftlists

@inject
@app.route('/giftlists/<reference>', methods=['DELETE'])
@token_required
def delete_giftlists(current_user, use_case: delete_gift_list.UseCase, reference):
    use_case.execute(delete_gift_list.Request(reference))

    return {
        'message': 'List Deleted'
    }

@inject
@app.route('/giftlists/<reference>/elements', methods=['POST'])
@token_required
def post_giftlist_element(current_user, use_case: create_gift_list_element.UseCase, reference):
    return use_case.execute(
        create_gift_list_element.Request(reference, request.json['url'])
    )

@inject
@app.route('/giftlists/<list_reference>/elements/<element_reference>', methods=['DELETE'])
@token_required
def delete_giftlist_element(
    current_user,
    use_case: delete_gift_list_element.UseCase,
    list_reference,
    element_reference
):
    use_case.execute(
        delete_gift_list_element.Request(
            list_reference,
            element_reference
        )
    )

    return {
        'message': 'List Element Deleted'
    }


import os
import logging
import shutil
import json

from packratAgent.Collection import Collection
from packratAgent.LocalRepoManager import LocalRepoManager, hashFile

MODULE_OWNER = 'packrat'

class AnsibleGalaxyManager( LocalRepoManager ):
  def __init__( self, *args, **kargs ):
    super().__init__( *args, **kargs )
    self.entry_map = {}

  def filePaths( self, filename, distro, distro_version, arch ):
    ( namespace, name, version ) = filename.split( '-' )
    version = version.strip( '.tar.gz' )

    name_path = os.path.join( self.repo_dir, 'api', 'collections', namespace, name, 'versions' )

    return [
             os.path.join( name_path, 'index.html' ),
             os.path.join( name_path, version, 'index.html' ),
             os.path.join( self.repo_dir, 'downloads', namespace, filename )
           ]

  def metadataFiles( self ):
    return [ os.path.join( self.repo_dir, 'api', 'index.html' ) ]

  def addEntry( self, type, filename, distro, distro_version, arch ):
    if type != 'galaxy':
      logging.warning( 'ansiblegalaxy: New entry not a ansible, skipping...' )
      return

    logging.debug( 'ansiblegalaxy: Got Entry for package: "%s"', filename )

    ( namespace, name, version ) = filename.split( '-' )
    version = version.strip( '.tar.gz' )

    if namespace not in self.entry_map:
      self.entry_map[ namespace ] = {}
    if name not in self.entry_map[ namespace ]:
      self.entry_map[ namespace ][ name ] = {}

    dir_path = os.path.join( self.repo_dir, 'downloads', namespace )
    file_path = os.path.join( dir_path, filename )

    size = os.path.getsize( file_path )
    ( _, sha256, _ ) = hashFile( file_path )

    collection = Collection( file_path )

    self.entry_map[ namespace ][ name ][ filename ] = ( version, size, sha256, collection.metadata )

  def removeEntry( self, filename, distro, distro_version, arch ):
    ( namespace, name, version ) = filename.split( '-' )
    version = version.strip( '.tar.gz' )

    try:
      del self.entry_map[ namespace ][ name ][ filename ]
      if not self.entry_map[ namespace ][ name ]:
        del self.entry_map[ namespace ][ name ]
      if not self.entry_map[ namespace ]:
        del self.entry_map[ namespace ]

    except KeyError:
      logging.warning( 'ansiblegalaxy: unable to remove entry "%s", ignored.', filename )

  def loadFile( self, filename, temp_file, distro, distro_version, arch ):
    ( namespace, name, _ ) = filename.split( '-' )

    dir_path = os.path.join( self.repo_dir, 'downloads', namespace )
    if not os.path.exists( dir_path ):
        os.makedirs( dir_path )

    file_path = os.path.join( dir_path, filename )
    shutil.move( temp_file, file_path )

  def writeMetadata( self ):
    api_path = os.path.join( self.repo_dir, 'api' )
    if not os.path.exists( api_path ):
      os.makedirs( api_path )

    api_metadata_map = {
                          'description': '{0} - {1}'.format( self.mirror_description, self.repo_description ),
                          'available_versions': { 'v2': '' }
                        }

    open( os.path.join( api_path, 'index.html' ), 'w' ).write( json.dumps( api_metadata_map ) )

    collections_path = os.path.join( api_path, 'collections' )
    if not os.path.exists( collections_path ):
      os.makedirs( collections_path )

    for namespace in self.entry_map.keys():
      for name in self.entry_map[ namespace ].keys():
        versions_path = os.path.join( collections_path, namespace, name, 'versions' )
        if not os.path.exists( versions_path ):
          os.makedirs( versions_path )

        result_list = []
        for filename, entry in self.entry_map[ namespace ][ name ].items():
          result_list.append( { 'version': entry[0] } )
          entry_map = {
                        'version': entry[0],
                        'namespace': { 'name': namespace },
                        'collection': { 'name': name },
                        'download_url': '{0}/downloads/{1}/{2}'.format( self.repo_url, namespace, filename ),
                        'artifact': { 'size': entry[1], 'sha256': entry[2] },
                        'metadata': entry[3]
                      }
          entry_path = os.path.join( versions_path, entry[0] )
          if not os.path.exists( entry_path ):
            os.makedirs( entry_path )

          open( os.path.join( entry_path, 'index.html' ), 'w' ).write( json.dumps( entry_map ) )

        version_map = {
                        'count': len( result_list ),
                        'next': None,
                        'previous': None,
                        'results': result_list
                      }

        logging.debug( 'ansiblegalaxy: writing version index for "%s"', namespace )
        open( os.path.join( versions_path, 'index.html' ), 'w' ).write( json.dumps( version_map ) )


#!/usr/bin/env python
# SPDX-License-Identifier: LGPL-3.0-only
# type: ignore

import sys
from unittest.mock import Mock

try:
    import tkinter as tk
except ImportError as _exc:
    sys.stderr.write("WARNING: {}\n".format(_exc))
    tk = Mock()
    ttk = Mock()

class HyperlinkManager:
    def __init__(self, text) -> None:
        self.text = text

        self.text.tag_config("hyper", underline=True)

        self.text.tag_bind("hyper", "<Enter>", self._enter)
        self.text.tag_bind("hyper", "<Leave>", self._leave)
        self.text.tag_bind("hyper", "<Button-1>", self._click)

        self.reset()

    def reset(self):
        """Remove all hyperlinks."""
        self.links = {}

    def add(self, action, p_id, p_Tags=[]):  # pylint: disable=W0102
        """
        Add a new hyper link.

        @param action: method that will be called for this hyperlink
        @param p_id: the arbitration id that we are associating this action.
        """
        # add an action to the manager.  returns tags to use in
        # associated text widget
        thetags = []
        uniquetag = "hyper-%d" % len(self.links)
        thetags.extend(p_Tags)
        thetags.append("hyper")
        thetags.append(uniquetag)
        self.links[uniquetag] = [action, p_id]
        return tuple(thetags)

    def _enter(self, event):  # pylint: disable=W0613
        self.text.config(cursor="hand2")

    def _leave(self, event):  # pylint: disable=W0613
        self.text.config(cursor="")

    def _click(self, event):  # pylint: disable=W0613
        """If somebody clicks on the link it will find the method to call."""
        for tag in self.text.tag_names(tk.CURRENT):
            if tag[:6] == "hyper-":
                self.links[tag][0](self.links[tag][1])

def getAllChildren(treeView, item=None):
    """Recursive generator of all the children item of the provided ttk.Treeview."""
    for c_currUID in treeView.get_children(item):
        yield c_currUID
        yield from getAllChildren(treeView, c_currUID)


import operator

OPCODES = {
    1: operator.add,
    2: operator.mul,
}

with open("day2.txt") as fp:
    data = fp.read()
    values = [int(i) for i in data.split(",")]
    values[1] = 12
    values[2] = 2

    for i in range(0, len(values), 4):
        chunk = values[i : i + 4]
        if chunk[0] in [1, 2]:
            op = OPCODES[chunk[0]]
            values[chunk[3]] = op(values[chunk[1]], values[chunk[2]])
        elif chunk[0] == 99:
            break
    print(",".join([str(x) for x in values]))


import threading
import socket
import json
import termcolor
import time
import numpy as np
import pandas as pd
host = '127.0.0.1'#server ip
port = 5555 #server port
#Create a new socket using the given address family, socket type and protocol number.
#ipv4 family
#TCP (SOCK_STREAM) is a connection-based protocol. The connection is established
#and the two parties have a conversation until the connection is terminated by one of the parties or by a network error.
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#	Allows a socket to bind to an address and port already in use.
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind((host, port)) #binidng port ip with server
server.listen()
clients = []
aliases = []

def specific_cast(message):
    """
    Forward mesages to client for whom message is meant by checking message header for sender and receiver.
    """
    receiver=message[2] #read message list 0 index
    index = aliases.index(receiver)
    client=clients[index]
    reliable_send(client,message)

# Function to handle clients'connections
def users_send():
    """
    Read username column from db and return
    """
    df=pd.read_csv('users.csv')
    new=df['username'].to_numpy().tolist()
    return new
def reliable_recv(target):
    """
    Receive as long as there is something to receive, can receive more than 1024 bytes
    """
    data = ''
    while True:
        try:
            #rstrip removes spaces at end
            data = data + target.recv(1024).decode().rstrip()
            return json.loads(data)
        except ValueError:
            continue

def reliable_send(target, data):
    """
    Reliable send, json object encoded as string

    """
    #json.dumps() takes in a json object and returns a string.

    jsondata = json.dumps(data)
    target.send(jsondata.encode())

def handle_client(client):
    """
    Works in different thread,
    handle every client connects with server
    checks header to call specific function
    """
    while True:
        try:
            message = reliable_recv(client)
            if str(message[0])=='messaging' and str(message[2])=='ALL':
                #messageing meant between specific clients
                broadcast(message)
            elif str(message[0])=='messaging':
                #if not broadcast
                specific_cast(message)

        except:
            index = clients.index(client)
            clients.remove(client)
            client.close()
            alias = aliases[index]
            aliases.remove(alias)
            #remove client if disconnected from list
            break
# Main function to receive the clients connection

def auth(name,password):
    """
    Loading users from db and comparing with fed name and password and returns true if authenticated
    """
    #checks for password and username parameters
    df=pd.read_csv('users.csv')
    row=df.loc[df['username']==name]
    isAuth=False
    row=np.array(row)
    if row.size:
        isAuth=row[0][1]==password
    return isAuth

def broadcast(message):
    """
    Broadcast messages ato all clients
    """
    for client in clients:
        reliable_send(client,message)
def receive():
    """
    Once User connects it, checks user credentials with db and send auth=true Response to clients, then client get authenticated.
    It also asks for clients name and then calls sender and receiver threads.
    """
    while True:
        print(termcolor.colored('[+] Server is Running! Waiting For The Incoming Connections ...', 'green'))
        client, address = server.accept()
        isAuth=False
        while not isAuth:
            data=reliable_recv(client)
            time.sleep(0.05)
            if data[0]=='auth':
                isAuth=auth(data[1],data[2])
                users_list=users_send()
                time.sleep(0.050)
                reliable_send(client,['auth_res',isAuth,users_list])
                time.sleep(0.050)
        time.sleep(2)
        print(termcolor.colored(str(address) + ' has connected!', 'green'))
        reliable_send(client,'alias?')
        alias = reliable_recv(client)
        aliases.append(alias)
        clients.append(client)
        print(f'The name of new client is {alias}')
        reliable_send(client,'you are now connected!')
        thread = threading.Thread(target=handle_client, args=(client,))
        thread.start()

receive()


# Apresentação
print('Programa para solicitar 2 vetores e somar eles de forma cruzada')
print()

# Declara e solicita os dados do 1º vetor
v1 = list()
print('Valores que irão compor o 1º vetor')
for i in range(17):
    valor = int(input('Informe um valor: '))
    v1.append(valor)
print()

# Declara e solicita os dados do 2º vetor
v2 = list()
print('Valores que irão compor o 2º vetor')
for i in range(17):
    valor = int(input('Informe um valor: '))
    v2.append(valor)
print()

# Declara o vetor que conterá os resultados
v3 = list()

# Posição correspondente em B. Inicia ela com a última posição do vetor
j = len(v2) - 1

# Percorre todas as posições de A
for i in range(len(v1)):
    # Faz a soma de 1 posição de v1 com uma de v2, e armazena em v3
    v3.append(v1[i] + v2[j])

    # Atualiza a variável de controle j
    j -= 1

# Apresenta os valores na tela
print()
print('Valores resultantes')
for v in v3:
    print(f'* {v}')


from base.game_2048 import game_2048

MAX_POWER = 11

class game_2048_binary_state(game_2048):
    def get_state(self):
        state = list(self.board.flatten())
        self.state = []  # assuming 2048 is the biggest number achievable
        for el in state:
            if el == 0:
                el = 1

            element_binary_value = '{0:011b}'.format(el)[::-1]
            self.state = self.state + [int(e) for e in element_binary_value]

        return self.state


"""module used to create a matrix containing the distances between the postcodes that specify the locations of the
 specified geographies"""

import os
import pandas as pd
from math import radians, sin, cos, sqrt, atan2
import csv
import datetime as dt

def calc_dist(inlat1, inlat2, inlong1, inlong2):
    """simple function that returns a distance between points given lat and longs of points.
    Takes curvature of earth into account"""
    R = 6373.0

    lat1 = radians(inlat1)
    lon1 = radians(inlong1)
    lat2 = radians(inlat2)
    lon2 = radians(inlong2)

    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))

    return R * c

def produce_distance_matrix(input_data, geog, lat, long):
    """ produces a matrix of distance between lat and logs for given level of geography. Produces separate files
    due to potential for a very large matrix for lower levels of geography. If joined would take the form:

       A B C
     A 0 2 4
     B 2 0 5
     C 4 5 0

    Where A, B and C represent the codes of the geographies.

    Requires:

    input_data - csv file of lat and longs of each item (e.g. lsoa, la, postcode etc)
    geog - the name of the column with the codes
    lat - name of the latitude column
    long - name of the longitude column
    """

    start_time = dt.datetime.now()
    print('Started at: ', start_time)

    # load lat and long data
    fields = [geog, lat, long]
    info_df = pd.read_csv(input_data, usecols=fields)

    # create lists from dataframe - faster to access than dataframes
    name_list = list(info_df[geog])
    lat_list = list(info_df[lat])
    long_list = list(info_df[long])

    # for each record in the input
    for i in range(0, len(info_df)):

        current = name_list[i]
        current_lat = lat_list[i]
        current_long = long_list[i]

        temp_out = []  # list to store  distance results

        # calculate distances to all other records in input
        for j in range(0, len(info_df)):
            temp_name = name_list[j]
            temp_lat = lat_list[j]
            temp_long = long_list[j]

            dist = calc_dist(current_lat, temp_lat, current_long,  temp_long)
            # investigate if putting zero distances to NaN makes finding min easier...

            # create lists of names and associated distances
            temp_out.append([temp_name, dist])

        # report on progress based on current records processed
        if i > 0 and i % 1000 == 0:
            time_now = dt.datetime.now()
            time_left = ((time_now - start_time).seconds/(i/len(name_list))) - (time_now - start_time).seconds
            finish_time = time_now + dt.timedelta(seconds=time_left)

            print('Row ', i, 'reached. Projected finish time is: ', finish_time)

        temp_out = [['lsoa11cd', current]] + temp_out

        out_file = os.path.join(os.getcwd(), 'lsoa distances', current + ".csv")
        # write to output file
        with open(out_file, 'w') as myfile:
            for row in temp_out:
                wr = csv.writer(myfile)
                wr.writerow(row)

# location of input data
os.chdir(os.path.join(os.getcwd(), 'raw_inputs'))
# input data to include
produce_distance_matrix('LSOA_L&L.csv', 'LSOA11CD', 'LATITUDE', 'LONGITUDE')


#17413번 단어 뒤집기2
s = input()
li = list()
start_tag = 0
end_tag = 0
for i in range(0, len(s)):
    if s[i] == "<": # >나올때까지 리스트에 추가
        start_tag = i
    elif s[i] == ">":
        if end_tag == start_tag:
            pass
        else:
            li.append(s[end_tag:start_tag])
        li.append(s[start_tag:i+1])
        end_tag = i+1
    elif i == len(s)-1:
        li.append(s[end_tag:])
for i in range(len(li)):
    if li[i][0] != "<":
        temp = li[i].split()
        ans = ''
        for j in temp:
            ans += ''.join(reversed(j))+" "
        li[i] = ans.rstrip()
print(*li, sep="")

    #마지막에 +" " 해서 split하기 쉽게 만들기

#< 또는 > 찾으면 문자열 찢어서 " " 넣기
#이러면 문자열 새로생성해야함. 메모리+
# <이랑 > 찾는 시간복잡도 n

# case 1
# s = input()
# li = list()
# for i in range(0, len(s)):
#     if s[i] == "<": # >나올때까지 리스트에 추가
#         if s[i-1] == " ":
#             continue
#         s = s[:i] + " " + s[i:]
#     elif s[i] == ">":
#         s = s[:i+1] + " " + s[i+1:]
# li = list(s.split())

DataStructure/data structure1 (practice)/string reverse 2.py


import matplotlib.pyplot as plt
import math

def pre_processing(filename):
    file = open(filename)
    lines = file.readlines()
    cities = [[]]
    n = int(lines[0])
    for l in lines[1:]:
        cities.append(list(map(float, l.split())))
    adj_mat = [[None] * (n+1)  for i in range(n+1)]

    x = [float(i[0]) for i in cities[1:]]
    y = [float(i[1]) for i in cities[1:]]
    plt.scatter(x, y)
    plt.show()

    for i in range(1, n+1):
        for j in range(1, n+1):
            if adj_mat[j][i]:
                adj_mat[j][i] = adj_mat[i][j]
            else:
                c1 = cities[i]
                c2 = cities[j]
                adj_mat[j][i] = math.sqrt((c1[0] - c2[0])**2 + (c1[1] - c2[1])**2)
    return adj_mat, n

def get_bin(n, bits):
    if n == 0:
        return [0]
    res = list()
    digit = n-1
    cur = 1 << digit
    while cur < 1 << bits:
        for i in get_bin(n-1, digit):
            res.append(cur|i)
        digit += 1
        cur = 1 << digit
    return res

def get_sets(n):
    sets = dict()
    for i in range(0, n + 1):
        #print(i)
        sets[i] = get_bin(i, n)
    return sets

#sets: dict
#keys: subproblem size
#value: binary set
def get_ele(set_hash):
    set_hash >>= 1
    k = 2
    res = set()
    while set_hash:
        if set_hash & 1:
            res.add(k)
        k += 1
        set_hash >>= 1
    return res

def TSP(n,adj_mat):

    sets = get_sets(n)
    A = {}
    #deal with base case
    for i in range(1<<n):
        A[i,1] = float("inf")
    A[1,1] = 0

    for m in range(2, n+1):
        print('m=', m)
        for subset in sets[m]:
            if subset & 1:
                elements = get_ele(subset)
                for j in elements:
                    min_ = float("inf")
                    for k in range(1, n+1):
                        if k!= j:
                            if (subset ^ 1<<j-1,k) in A:
                                min_ = min(min_, A[subset ^ 1<<j-1, k] + adj_mat[k][j])
                            A[subset,j] = min_
    return A
if __name__ == '__main__':
    n, adj_mat = pre_processing('tsp.txt')
    A = TSP(n,adj_mat)
    res = float("inf")
    for j in range(2, n+1):
        res = min(res, A[(1<<n)-1, j] + adj_mat[j][1])
    print(res)


from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.views.generic import FormView
from atelier.models import Profile
from django.views import generic
from atelier.forms import ProfileRegisterForm, ProfileChangeForm
from django.urls import reverse_lazy
from atelier.views.base_view import AtelierFilterObjectsPreMixin, BaseListView, TailorPermissionPreMixin, \
    BaseDetailView, BaseDeleteView, BaseUpdateView

class ProfileDetailView(TailorPermissionPreMixin, AtelierFilterObjectsPreMixin, BaseDetailView):
    model = Profile
    fields = '__all__'

class ProfileListView(AtelierFilterObjectsPreMixin, TailorPermissionPreMixin, BaseListView):
    model = Profile

class ProfileCreateView(TailorPermissionPreMixin, FormView):
    template_name = 'atelier/create_form.html'
    form_class = ProfileRegisterForm

    def get_initial(self):
        """
        Returns the initial data to use for atelier form field.
        """
        initial = super().get_initial()
        initial['atelier'] = self.request.user.profile.atelier
        return initial

    def get_success_url(self):
        return reverse_lazy('atelier:profile_list')

    def form_valid(self, form):
        # The default implementation for form_valid() simply redirects to the success_url.
        user = User.objects.create(
            email=form.cleaned_data['email'],
            username=form.cleaned_data['username'],
        )
        user.set_password(form.cleaned_data['password2'])
        user.save()
        Profile.objects.create(
            user=user,
            atelier=self.request.user.profile.atelier,
            is_tailor=form.cleaned_data['is_tailor'],
            created_by=self.request.user,
            last_updated_by=self.request.user,
        )
        return super().form_valid(form)

class ProfileChangeView(AtelierFilterObjectsPreMixin, TailorPermissionPreMixin, BaseUpdateView):
    model = Profile
    template_name = 'atelier/create_form.html'
    form_class = ProfileChangeForm

    def get_success_url(self):
        return reverse_lazy('atelier:profile_list')

    def get_profile_object(self):
        profile_id = self.kwargs.get('pk')
        return Profile.objects.get(id=profile_id)

    def get_initial(self):
        data = {
            'email': self.get_profile_object().user.email,
            'is_tailor': self.get_profile_object().is_tailor
        }
        return data

    def form_valid(self, form):
        # The default implementation for form_valid() simply redirects to the success_url.
        profile = self.get_profile_object()
        profile.is_tailor = form.cleaned_data['is_tailor']
        profile.user.email = form.cleaned_data['email']
        profile.last_updated_by = self.request.user
        profile.full_clean()
        profile.save()
        profile.user.save()
        return super().form_valid(form)

class ProfileDeleteView(TailorPermissionPreMixin, AtelierFilterObjectsPreMixin, BaseDeleteView):
    model = Profile
    success_url = reverse_lazy('atelier:profile_list')
    template_name = 'atelier/delete_form.html'

    def get_user_object(self):
        profile_id = self.kwargs.get('pk')
        profile = Profile.objects.get(pk=profile_id)
        return profile.user

    def delete(self, request, *args, **kwargs):
        """
        Overriding the delete() method to delete User instances, and according Profile instance will be deleted too.
        """
        self.object = self.get_user_object()
        success_url = self.get_success_url()
        self.object.delete()
        return HttpResponseRedirect(success_url)

    def get_success_url(self):
        return reverse_lazy('atelier:profile_list')


# s1 - s2 = x(given)
# s1 + s2 = sum(list)
#s1= (sum(list) +x) / 2
#problem reduced to subset sum

n = int(input())
l = list(map(int, input().split()))
diff = int(input())

s = sum(l) + diff

W= s//2

dp = [[None for i in range(W+1)] for j in range(n+1)]

def subsetsum(l, n, W):

  if(W==0):
    return 1

  if(n==0):
    return 0

  if(dp[n][W]!=None):
    return dp[n][W]

  if(W >= l[n-1]):
    ans = subsetsum(l, n-1, W-l[n-1]) + subsetsum(l, n-1, W)
    dp[n][W] = ans
    return ans

  else:
    ans = subsetsum(l, n-1, W)
    dp[n][W] = ans
    return ans

print(subsetsum(l, n, W))


# Dance Hall задача 5; Прости пресмятания
from math import pow
length = float(input()) * 100
width = float(input()) * 100
hall_area = length * width
#
wardrobe_a = float(input()) * 100
#
bench = hall_area / 10
#
dancer = 40
dancer_space = float(7000)
#
wardrobe_area = wardrobe_a * wardrobe_a
#
free_area = hall_area - wardrobe_area - bench
#
dancers_count = int(free_area / (40 + 7000))
#
print(dancers_count)
#

Programming Basics with Python/2_simple_opeartions_and_calculations/exercise_simple_ops/dance_hall.py


import math
from typing import List
import os
from app.resources.logger import logger

def get_block_entropy(block: bytes, block_size: int) -> float:
    # start counters
    counters = {byte: 0 for byte in range(2 ** 8)}
    for byte in block:
        counters[byte] += 1
    # calculate probabilities for each byte
    probabilities = [counter / block_size for counter in counters.values()]
    # final sum
    entropy = -sum(
        probability * math.log2(probability)
        for probability in probabilities if probability > 0
        )
    return entropy

def get_file_entropy(file_name: str, block_size: int) -> List[float]:
    entropy_detail = []
    f = open(file_name, "rb")
    block = f.read(block_size)
    # get entropy for each block
    while block:
        entropy = get_block_entropy(block, block_size)
        entropy_detail.append(float(f'{entropy:.2f}'))
        block = f.read(block_size)
    f.close()
    return entropy_detail

def get_entropy_summary(entropy_detail: List[float]) -> dict:
    low_entropy_blocks = len([x for x in entropy_detail if x < 2])
    high_entropy_blocks = len([x for x in entropy_detail if x > 7])
    entropy_summary = {
        "low_entropy_blocks": low_entropy_blocks,
        "high_entryopy_blocks": high_entropy_blocks
    }
    return entropy_summary

def delete_saved_file(file_name: str) -> None:
    if os.path.exists(file_name):
        os.remove(file_name)

def generate_entropy_report(file_name: str, block_size: int) -> dict:
    try:
        entropy_detail = get_file_entropy(file_name, block_size)
        entropy_summary = get_entropy_summary(entropy_detail)
        response = {
            "entropyDetail": entropy_detail,
            "summary": entropy_summary
        }
        delete_saved_file(file_name)
        return response
    except Exception as e:
        logger.error(f"Exception raised: {e} , deleting saved file.")
        delete_saved_file(file_name)
        raise e


import argparse
import pygame as pg

def create_circle(size, circle_color, background_color, filename):
  # margin = int(0.1 * size)
  margin = 0
  screen = pg.display.set_mode((2 * size + margin, 2 * size + margin))
  screen.fill(background_color)
  x = screen.get_width() // 2
  y = screen.get_height() // 2
  pg.draw.circle(screen, circle_color, (x, y), size)
  pg.image.save(screen, filename)

def create_cell(genome):
  colors = {'red': (255,0,0), 'green': (0,255,0), 'blue': (0,0,255), 'darkBlue': (0,0,128),
            'white': (255,255,255), 'black': (0,0,0), 'pink': (255,200,200)}
  if genome == '00':
    screen = pg.display.set_mode((20, 20))
    screen.fill(colors['black'])
    pg.image.save(screen, 'images/' + genome + '.png')
  elif genome == '01':
    screen = pg.display.set_mode((40, 20))
    screen.fill(colors['white'])
    pg.draw.rect(screen, colors['black'], (0, 0, 20, 20))
    pg.draw.polygon(screen, colors['black'], [(20, 0), (20, 20), (40, 10)])
    pg.image.save(screen, 'images/' + genome + '.png')
  elif genome == '10':
    screen = pg.display.set_mode((60, 20))
    screen.fill(colors['white'])
    pg.draw.polygon(screen, colors['black'], [(20, 0), (40, 0), (40, 20), (20, 20)])
    pg.draw.polygon(screen, colors['black'], [(0, 10), (20, 0), (20, 20)])
    pg.draw.polygon(screen, colors['black'], [(40, 0), (40, 20), (60, 10)])
    pg.image.save(screen, 'images/' + genome + '.png')
  else:
    screen = pg.display.set_mode((60, 40))
    screen.fill(colors['white'])
    pg.draw.polygon(screen, colors['black'], [(20, 0), (40, 0), (40, 20), (20, 20)])
    pg.draw.polygon(screen, colors['black'], [(0, 10), (20, 0), (20, 20)])
    pg.draw.polygon(screen, colors['black'], [(40, 0), (40, 20), (60, 10)])
    pg.draw.polygon(screen, colors['black'], [(20, 20), (40, 20), (30, 40)])
    pg.image.save(screen, 'images/' + genome + '.png')

def create_triangle(colors):
  screen = pg.display.set_mode((20, 20))
  screen.fill(colors['white'])
  # pg.draw.polygon(screen, colors['black'], [(0, 10), (20, 0), (20, 20)])
  pg.draw.polygon(screen, colors['black'], [(0, 0), (0, 20), (20, 10)])
  pg.image.save(screen, 'images/triangle.png')

if __name__ == '__main__':
  colors = {'red': (255,0,0), 'green': (0,255,0), 'blue': (0,0,255), 'darkBlue': (0,0,128),
            'white': (255,255,255), 'black': (0,0,0), 'pink': (255,200,200)}

  # create_circle(30, colors['black'], colors['white'], 'images/black_circle_30.png')
  # create_triangle(colors)
  create_cell('11')


import sys
import gammalib
from utils import *
import numpy as np
import matplotlib.pyplot as plt

# first input is XML file name
models = gammalib.GModels(sys.argv[1])
# second and third input are minimum and maximum energy in TeV
emin = float(sys.argv[2])
emax = float(sys.argv[3])

lons, lats, radii, fluxes, names = dist_from_gammalib(models, emin=emin,emax=emax)

# binning
logs_min = int(np.floor(np.log10(np.min(fluxes))))
logs_max = int(np.ceil(np.log10(np.max(fluxes))))
nbins = 10 * (logs_max - logs_min)
bins_lognlogs = np.logspace(logs_min, logs_max, nbins)

fig1 = plt.figure('LogNLogS')
ax1 = plt.subplot()
ax1.set_xscale('log')
ax1.set_yscale('log')
ax1.set_xlabel("Flux {}-{} TeV (Crab units)".format(emin,emax), fontsize=14)
ax1.set_ylabel('Number of sources (> Flux)', fontsize=14)
format_ax(ax1)

ax1.hist(fluxes, bins=bins_lognlogs, density=False, histtype='step', cumulative=-1)

try:
    if sys.argv[4] == 'check_flux':
        for s, flux in enumerate(fluxes):
            if flux > 1.:
                msg = "Source {} has flux of {} Crab".format(names[s],flux)
                print(msg)
except:
    pass

plt.show()