Mais

Script Python para classes de recursos (loop, classificar, mesclar e substituir)


Isso é o que eu tenho que fazer usando um script Python para ArcGIS 10.1:

  1. Faça um loop por todas as classes de recursos e, primeiro, adicione um campo e, em seguida, escreva o nome da classe de recursos no campo adicionado.
  2. Mescle todas as classes de recursos de 1. em uma classe de recursos chamada OSRS_ORN_NER.
  3. Classifique esta classe de recurso por HWY_NUM e substitua OSRS_ORN_NER pelo classificado.

Este é o código que tenho para isso até agora:

Acho que a primeira parte do código está certa, mas não sei se fiz a segunda certa ou se estou no caminho certo para a última parte. Além disso, como exatamente eu executaria um script python no ArcGIS? Qualquer ajuda seria ótimo!

código:

import arcpy, os arcpy.env.workspace = r'W:  S&P  s & p techs  Emily  TownshipsDissolved  FinalDissolved.gdb '# Fazendo loop pelas classes de feições dissolvidas, adicionando o campo' Nome 'e escrevendo # nome da classe de feições no campo adicionado . para fc em arcpy.ListFeatureClasses (): arcpy.AddField_management (fc, "Name", "TEXT", field_length = 50) com arcpy.da.UpdateCursor (fc, "Name") como cursor: para linha no cursor: linha [ 0] = fc cursor.updateRow (row) # Mesclando as várias classes de recursos em uma chamada OSRS_ORN_NER list = [] para r na linha: list.append (r) arcpy.Merge_management (list, "W:  S&P  s & p techs  Emily  TownshipsDissolved  FinalDissolved.gdb  OSRS_ORN_NER ") # Classificando por HWY_NUM_PR e substituindo OSRS_ORN_NER pela classe de recurso classificada Sort_management (" OSRS_ORN_NER "," OSRS_ORN_NER_new ", [[" HWY_NUM_PR "]," ASCEND)

Você precisa primeiro atribuir oListFeatureClasses ()a uma variável para que você possa chamá-la mais tarde para a fusão

import arcpy, os arcpy.env.workspace = r'W:  S&P  s & p techs  Emily  TownshipsDissolved  FinalDissolved.gdb 'fcs = arcpy.ListFeatureClasses () para fc em fcs: arcpy.AddField_management (fc, "Nome", "TEXT", field_length = 50) com arcpy.da.UpdateCursor (fc, "Name") como cursor: para linha no cursor: linha [0] = fc cursor.updateRow (linha) mergeOutput = r "W:  S&P  s & p techs  Emily  TownshipsDissolved  FinalDissolved.gdb  OSRS_ORN_NER "sortOutput = r" W:  S&P  s & p techs  Emily  TownshipsDissolved  FinalDissolved.gdb  OSRS_ORN_NER_new "arcpy.Merge_management.Merge_management (fcs, mergeOutput. , [["HWY_NUM_PR", "ASCENDING"]])

parece estar bem, mas você deve inicializar sua lista antes de fazer um loop no fc, e indentá-lo corretamente anexando os nomes fc à sua lista

para fc em arcpy.ListFeatureClasses (): list.append (fc)… arcpy.Merge_management (list, outputname) arcpy.Sort_management (outputname, finalname, [["HWY_NUM_PR", "ASCENDING"]])

Como posso saber onde meu script Python está travado?

Então, estou depurando meu programa Python e encontrei um bug que faz o programa travar, como se estivesse em um loop infinito. Bem, eu tive um problema com um loop infinito antes, mas quando ele desligou, eu poderia matar o programa e o python cuspiu uma exceção útil que me disse onde o programa foi encerrado quando enviei o comando kill. Agora, no entanto, quando o programa desliga e eu pressiono-o com o Ctrl-c, ele não aborta, mas continua em execução. Posso usar alguma ferramenta para localizar o desligamento? Eu sou novo em criação de perfil, mas pelo que sei, um criador de perfil só pode fornecer informações sobre um programa que foi concluído com êxito. Ou você pode usar um criador de perfil para depurar tais travamentos?


O que chamamos de web scraping?

Web scraping é um processo automatizado de coleta de dados públicos. Os web scrapers extraem automaticamente grandes quantidades de dados públicos de sites de destino em segundos.

Este tutorial de web scraping em Python funcionará para todos os sistemas operacionais. Haverá pequenas diferenças ao instalar Python ou ambientes de desenvolvimento, mas não em qualquer outra coisa.

  • Construindo um raspador da web: preparação em Python
  • Chegando às bibliotecas
  • WebDrivers e navegadores
  • Encontrar um lugar aconchegante para nosso raspador de web Python
  • Importando e usando bibliotecas
  • Escolha um URL
  • Definição de objetos e construção de listas
  • Extração de dados com nosso web scraper Python
  • Exportando os dados
  • Mais listas. Mais!
  • Web scraping com as práticas recomendadas do Python
  • Conclusão

Quais seções de Python devo aprender para ArcGis?

Eu quero aprender python para ArcGis. Eu comprei & quotAutomatize as coisas chatas com python. & Quot É & # x27s um livro divertido, mas é grande! Em quais seções / código devo focar ao aprender Python for ArcGis? Por exemplo, devo me concentrar no loop & quotwhile & quot etc? Obrigado!

Você deve trabalhar o livro inteiro. Não leva muito tempo. É onde eu comecei e fazer tudo isso lhe dará uma boa base antes de entrar em python para GIS.

É um livro que você me recomenda comprar? Já trabalhei com R antes, sei como fazer algumas ações básicas de consulta: pe isso & # x27 é isso.

Sim, nas aulas que fiz, percorremos literalmente toda a lista do Toolbox, focando mais nos recursos de processamento obscuros que realmente deveriam ser executados em Python de qualquer maneira.

Também é ótimo revisar a teoria e os problemas de programação. Eu não tinha ideia dos problemas de programação (como depurar todos os diferentes tipos de erro) até fazer um curso de comp sci.

Muitas das funções GIS (como a execução de ferramentas de geoprocessamento) de que você precisa com o arcpy são bastante específicas do esri, portanto, ao aprender python não-GIS, é principalmente um entendimento básico da estrutura de um script (configuração de variáveis, sintaxe, importar bibliotecas, etc.) e aprender a repetir coisas, como percorrer uma pasta de arquivos.

Rompa com o arcpy o mais rápido possível. Existe um enorme mundo de ferramentas e opções por aí.

Acho que & quotthe básico & quot estão nos capítulos 1-10. Mas eu continuaria depois disso. O livro inteiro é bom.

Os tipos de dados são importantes e os métodos para verificá-los e resumi-los.

Zip para iterar em vários itens ao mesmo tempo

Compreensão de lista, especialmente para construir strings personalizadas

Então descubra como a documentação do arcgis é totalmente útil agora com o arcpy

Em seguida, google seu problema com site: stackexchange.com para obter exemplos, explicações e notas sobre o seu problema e aprenda.

Reutilize seu código. Salve uma versão antes de fazer alterações significativas.

Depois que tudo estiver indo bem, você pode olhar para ambientes conda ou ambientes virtuais para apresentar análises muito interessantes, aprendizado estatístico, gráficos, bibliotecas de transformação de dados.

Incluindo o notebook jupyter, que permite fácil teste de código e autodocumentação, mesmo para iniciantes.

A qualquer momento ao longo do caminho ou depois que você tiver tempo e interesse, leia e trabalhe um livro o mais longe que puder. Eu recomendo Learning Python da OReilly Press.


Python é um dos muitos softwares aplicativos de programação orientada a objetos de código aberto disponíveis no mercado. Alguns dos muitos usos do Python são o desenvolvimento de aplicativos, implementação do processo de teste de automação, permite a construção de programação múltipla, biblioteca de programação totalmente construída, pode ser usado em todos os principais sistemas operacionais e plataformas, acessibilidade do sistema de banco de dados, código simples e legível, fácil de aplicar em processos complexos de desenvolvimento de software, ajuda na abordagem de desenvolvimento de aplicativo de software orientado por teste, aprendizado de máquina / análise de dados, ajuda no reconhecimento de padrões, com suporte em várias ferramentas, permitido por muitas das estruturas provisionadas, etc.

10 usos importantes do Python

Python pode ser mais amigável devido às suas vantagens. Veja abaixo os usos da linguagem python por diferentes motivos:

Desenvolvimento Web, linguagens de programação, teste de software e outros

1. Aplicativos

Python pode ser usado para desenvolver diferentes aplicativos, como aplicativos da web, aplicativos baseados em interface gráfica do usuário, aplicativo de desenvolvimento de software, aplicativos científicos e numéricos, programação de rede, jogos e aplicativos 3D e outros aplicativos de negócios. Faz uma interface interativa e fácil desenvolvimento de aplicações.

2. Múltiplos paradigmas de programação

Ele também é usado por fornecer suporte contínuo a vários paradigmas de programação, uma vez que oferece suporte à programação orientada a objetos e à programação estruturada. Python possui recursos que também oferecem suporte a vários conceitos de linguagem de programação funcional. É usado para sistema de tipo dinâmico e gerenciamento automático de memória. Os recursos da linguagem Python e os paradigmas de programação permitem o desenvolvimento de aplicativos pequenos e grandes. Ele pode ser usado para aplicativos de software complexos.

3. Biblioteca padrão robusta

Ele tem uma biblioteca padrão grande e robusta para usar no desenvolvimento de aplicativos. Também faz com que os desenvolvedores usem Python em vez de outras linguagens. A biblioteca padrão ajuda você a usar a gama diferente de módulos disponíveis para Python, pois este módulo ajuda a adicionar a funcionalidade sem escrever mais nenhum código. Para obter informações sobre vários módulos, a documentação da biblioteca padrão do python pode ser consultada. Ao desenvolver qualquer aplicativo da web, implementar serviços da web, executar operações de string e outros usos como protocolo de interface, a documentação da biblioteca padrão ajuda.

4. Compatível com as principais plataformas e sistemas

É compatível principalmente com as principais plataformas e sistemas, por isso é usado principalmente para o desenvolvimento de aplicativos. Com a ajuda de interpretadores python, o código python pode ser executado em plataformas e ferramentas específicas, pois oferece suporte a muitos sistemas operacionais. Como python é uma linguagem de programação interpretada de alto nível e permite que você execute o código em várias plataformas. O código novo e modificado pode ser executado sem recompilar e seu impacto pode ser monitorado ou verificado. Isso significa que não é necessário recompilar o código após cada alteração. Esse recurso ajuda a economizar tempo de desenvolvimento dos desenvolvedores.

5. Acesso ao banco de dados

O uso de Python também ajuda a acessar o banco de dados facilmente. Python ajuda a personalizar as interfaces de diferentes bancos de dados como MySQL, Oracle, Microsoft SQL Server, PostgreSQL e outros bancos de dados. Possui um banco de dados de objetos como Durus e ZODB. É usado para API de banco de dados padrão e está disponível gratuitamente para download.

6. Legibilidade do código

O código Python é fácil de ler e manter. Também é facilmente reutilizável onde for necessário. O Python tem uma sintaxe simples, o que permite que os diferentes conceitos se desenvolvam sem escrever nenhum código adicional. O código deve ser de boa qualidade e fácil de manter o código-fonte e simplificar a manutenção, que é necessária para desenvolver o aplicativo de software. Ele também enfatiza a legibilidade do código, que é um ótimo recurso, ao contrário de outras linguagens de programação. Ajuda a construir aplicativos personalizados e o código limpo ajuda a manter e atualizar os aplicativos de software sem colocar esforço extra no mesmo código.

7. Simplifique o desenvolvimento de software complexo

Os aplicativos do Python são usados ​​para simplificar o complexo processo de desenvolvimento de software, pois é uma linguagem de programação de propósito geral. É usado para desenvolver aplicações complexas como aplicações científicas e numéricas e para aplicações desktop e web. Python tem recursos como análise de dados e visualização, o que ajuda na criação de soluções personalizadas sem colocar esforço e tempo extra. Ajuda você a visualizar e apresentar dados de forma eficaz.

8. Muitos frameworks e ferramentas de código aberto

Python é um software livre e facilmente disponível. Isso também ajuda a custar significativamente o desenvolvimento de software. Existem muitos aplicativos de código aberto de estruturas, bibliotecas e ferramentas de desenvolvimento Python para desenvolver o aplicativo sem colocar custos extras. Os frameworks Python simplificam e tornam o processo mais rápido para o desenvolvimento de aplicativos web, e os frameworks são Django, Flask, pirâmide, etc. Os frameworks Python GUI estão disponíveis para desenvolver o aplicativo baseado em GUI.

9. Adote o Desenvolvimento Orientado a Testes

O Python torna a codificação e os testes mais fáceis com a ajuda da adoção da abordagem de Desenvolvimento Orientado a Testes. Os casos de teste podem ser facilmente escritos antes de qualquer desenvolvimento de código. Sempre que o desenvolvimento do código é iniciado, os casos de teste escritos podem começar a testar o código simultaneamente e fornecer o resultado. Eles também podem ser usados ​​para verificar ou testar os pré-requisitos com base no código-fonte.

10. Outros aplicativos para os quais o python é usado

Existem outros aplicativos para os quais o python é usado: robótica, web scraping, script, inteligência artificial, análise de dados, aprendizado de máquina, detecção de rosto, detecção de cores, aplicativos CAD 3D, aplicativos baseados em console, aplicativos baseados em áudio, baseados em vídeo aplicativos, aplicativos corporativos e aplicativos para imagens, etc. Estes são alguns dos principais aplicativos usados.

Conclusão

Neste artigo Usos do Python, vimos que o python é uma das principais linguagens usadas para desenvolver aplicativos de desktop e da web. Python possui recursos que cuidam de tarefas comuns de programação. Python é simples de aprender e fácil de usar. Às vezes, o python é marcado como mais lento do que outras linguagens de programação amplamente utilizadas, como Java. Os aplicativos Python podem ser acelerados simplesmente mantendo o código e usando o tempo de execução personalizado.

Python oferece suporte aos módulos e pacotes, o que incentiva a modularidade do programa e a reutilização de código. Python fornece um aumento na produtividade, o que o torna a primeira escolha dos desenvolvedores. Possui uma ótima curva de aprendizado, pois suporta linguagem de programação funcional e procedural. É open source e pode ser distribuído gratuitamente. A linguagem de programação selecionada principalmente com base no requisito e compatibilidade com plataformas e banco de dados.

Artigos Recomendados

Este foi um guia para o uso da linguagem Python. Aqui, discutimos os diferentes usos do Python, como acesso fácil ao banco de dados, desenvolvimento de software, confiabilidade do código, biblioteca padrão robusta em detalhes. Você também pode consultar os seguintes artigos para saber mais & # 8211


5. Múltiplas operações de substituição: substitua vários padrões com a mesma string

Substitua qualquer um de foo, bar ou baz por foobar

Uma boa ferramenta de substituição do Linux é rpl, que foi originalmente escrito para o projeto Debian, então está disponível com apt-get install rpl em qualquer distribuição derivada do Debian, e pode ser para outras, mas caso contrário, você pode baixar o arquivo tar.gz do SourceForge.

Observe que, se a string contiver espaços, ela deve ser colocada entre aspas. Por padrão, o rpl cuida de letras maiúsculas mas não de palavras completas, mas você pode alterar esses padrões com as opções -i (ignorar maiúsculas e minúsculas) e -w (palavras inteiras). Você também pode especificar vários arquivos:

Ou até mesmo especificar o extensões (-x) para pesquisar ou mesmo pesquisar recursivamente (-R) no diretório:

Você também pode pesquisar / substituir em modo interativo com a opção -p (prompt):

A saída mostra o número de arquivos / string substituídos e o tipo de pesquisa (maiúsculas / minúsculas, palavras inteiras / parciais), mas pode ser silencioso com o -q (modo silencioso), ou ainda mais detalhado, listando os números de linha que contêm correspondências de cada arquivo e diretório com -v (modo verboso) opção.

Outras opções que vale a pena lembrar são -e (honra escapes) que permitem expressões regulares, então você também pode pesquisar tabs ( t), novas linhas ( n), etc. Você pode usar -f para forçar permissões (claro, somente quando o usuário tem permissão de escrita) e -d para preservar os tempos de modificação`).

Finalmente, se você não tiver certeza do que exatamente vai acontecer, use o -s (modo de simulação).


Um programa completo: solicitações assíncronas

Você chegou até aqui e agora é a hora da parte divertida e indolor. Nesta seção, você & rsquoll construirá um coletor de URL de web scraping, areq.py, usando aiohttp, uma estrutura cliente / servidor HTTP assíncrona incrivelmente rápida. (Precisamos apenas da parte do cliente.) Essa ferramenta poderia ser usada para mapear conexões entre um cluster de sites, com os links formando um gráfico direcionado.

Observação: Você pode estar se perguntando por que o Python & rsquos solicita o pacote isn & rsquot compatível com IO assíncrono. O request é construído em cima do urllib3, que por sua vez usa Python & rsquos http e módulos socket.

Por padrão, as operações de soquete estão bloqueando. Isso significa que Python ganhou & rsquot como await requests.get (url) porque .get () não está aguardando. Em contraste, quase tudo em aiohttp é uma corrotina aguardável, como session.request () e response.text (). Caso contrário, é um ótimo pacote, mas você deve prestar um desserviço a si mesmo usando solicitações em código assíncrono.

A estrutura de alto nível do programa será semelhante a esta:

Leia uma sequência de URLs de um arquivo local, urls.txt.

Envie solicitações GET para os URLs e decodifique o conteúdo resultante. Se isso falhar, pare aqui para ver um URL.

Pesquise os URLs nas tags href no HTML das respostas.

Escreva os resultados em foundurls.txt.

Faça todas as opções acima da maneira mais assíncrona e simultânea possível. (Use aiohttp para as solicitações e aiofiles para os anexos de arquivo. Esses são dois exemplos principais de IO adequados para o modelo de IO assíncrono.)

Aqui está o conteúdo de urls.txt. Não é muito grande e contém principalmente sites de alto tráfego:

O segundo URL na lista deve retornar uma resposta 404, que você deve manipular normalmente. Se você estiver executando uma versão expandida deste programa, provavelmente precisará lidar com problemas muito mais complicados do que este, como desconexões de servidor e redirecionamentos sem fim.

As próprias solicitações devem ser feitas usando uma única sessão, para aproveitar a reutilização do pool de conexão interna da sessão e rsquos.

Vamos dar uma olhada no programa completo. Nós iremos percorrer as coisas passo a passo depois de:

Este script é mais longo do que nossos programas de brinquedo iniciais, então vamos decompô-lo.

A constante HREF_RE é uma expressão regular para extrair o que procuramos, tags href em HTML:

A co-rotina fetch_html () é um wrapper em torno de uma solicitação GET para fazer a solicitação e decodificar o HTML da página resultante. Ele faz a solicitação, aguarda a resposta e levanta imediatamente no caso de um status diferente de 200:

Se o status estiver ok, fetch_html () retorna a página HTML (a str). Notavelmente, não há tratamento de exceção feito nesta função. A lógica é propagar essa exceção para o autor da chamada e deixá-la ser tratada lá:

Aguardamos session.request () e resp.text () porque eles & rsquore co-rotinas aguardáveis. Caso contrário, o ciclo de solicitação / resposta seria a parte demorada e demorada do aplicativo, mas com IO assíncrono, fetch_html () permite que o loop de eventos funcione em outros trabalhos prontamente disponíveis, como análise e gravação de URLs que já foram buscados .

Em seguida na cadeia de corrotinas vem parse (), que espera em fetch_html () para um determinado URL e, em seguida, extrai todas as tags href dessa página & rsquos HTML, certificando-se de que cada uma é válida e formatando-a como um caminho absoluto.

É certo que a segunda parte de parse () está bloqueando, mas consiste em uma correspondência rápida de regex e garantindo que os links descobertos sejam transformados em caminhos absolutos.

Nesse caso específico, esse código síncrono deve ser rápido e discreto. Mas lembre-se de que qualquer linha em uma determinada co-rotina bloqueará outras co-rotinas, a menos que essa linha use yield, await ou return. Se a análise foi um processo mais intenso, você pode querer considerar a execução desta parte em seu próprio processo com loop.run_in_executor ().

Em seguida, a co-rotina write () pega um objeto de arquivo e um único URL e espera em parse () para retornar um conjunto de URLs analisados, gravando cada um no arquivo de forma assíncrona junto com seu URL de origem por meio do uso de aiofiles, um pacote para arquivo assíncrono IO.

Por último, bulk_crawl_and_write () serve como o ponto de entrada principal na cadeia de corrotinas do script e rsquos. Ele usa uma única sessão e uma tarefa é criada para cada URL lida em urls.txt.

Aqui estão alguns pontos adicionais que merecem menção:

O ClientSession padrão possui um adaptador com no máximo 100 conexões abertas. Para mudar isso, passe uma instância de asyncio.connector.TCPConnector para ClientSession. Você também pode especificar limites por host.

Você pode especificar tempos limites máximos para a sessão como um todo e para solicitações individuais.

Este script também usa async com, que funciona com um gerenciador de contexto assíncrono. Não dediquei uma seção inteira a esse conceito porque a transição de gerenciadores de contexto síncronos para assíncronos é bastante direta. O último deve definir .__ aenter __ () e .__ aexit __ () em vez de .__ exit __ () e .__ inserir __ (). Como você pode esperar, async com só pode ser usado dentro de uma função de co-rotina declarada com async def.

Se você quiser explorar um pouco mais, os arquivos complementares para este tutorial no GitHub também têm comentários e docstrings anexados.

Aqui está a execução em toda a sua glória, pois areq.py obtém, analisa e salva os resultados para 9 URLs em menos de um segundo:

Isso não é muito ruim! Como verificação de integridade, você pode verificar a contagem de linha na saída. No meu caso, é 626, embora tenha em mente que isso pode oscilar:

Próximos passos: Se você quiser aumentar a aposta, torne este webcrawler recursivo. Você pode usar o aio-redis para controlar quais URLs foram rastreados na árvore para evitar solicitá-los duas vezes e conectar links com a biblioteca Python & rsquos networkx.

Lembre-se de ser legal. Enviar 1000 solicitações simultâneas para um site pequeno e desavisado é ruim, ruim, ruim. Existem maneiras de limitar quantas solicitações simultâneas você deve fazer em um lote, como usar os objetos sempahore de asyncio ou usar um padrão como este. Se você não prestar atenção a este aviso, poderá obter um lote enorme de exceções TimeoutError e apenas acabar prejudicando seu próprio programa.


1 resposta 1

Obrigado por compartilhar seu código!

Não vou cobrir todas as suas perguntas, mas vou tentar o meu melhor.

(aviso, longa postagem recebida)

Minha implementação está correta? (Os testes dizem isso)

Tanto quanto eu tentei quebrá-lo, eu diria que sim, está correto. Mas veja abaixo métodos de teste mais completos.

Pode ser acelerado?

A primeira coisa que fiz foi alterar ligeiramente o perfil do seu arquivo de teste (chamei-o de test_heap.py) para propagar a geração da lista aleatória. Eu também alterei a chamada random.sample para ser mais flexível com o parâmetro sample_size.

Portanto, a população de random.sample é sempre maior do que meu sample_size. Talvez haja uma maneira melhor?

Também defini o tamanho da amostra como 50000 para ter um tamanho decente para a próxima etapa.

O próximo passo foi perfilando o código com python -m cProfile -s cumtime test_heap.py. Se você não estiver familiarizado com o criador de perfil, consulte o documento. Eu lanço o comando algumas vezes para obter uma noção das variações de tempo, o que me dá uma linha de base para otimização. O valor original era:

Agora temos uma meta a vencer e algumas informações sobre o que leva tempo. Não colei a lista inteira de chamadas de função, é bem longa, mas você entendeu.

Muito tempo é gasto em _siftdown e muito menos em _siftup, e algumas funções são chamadas muitas vezes, então vamos ver se podemos consertar isso.

(Eu deveria ter começado com _siftdown, que era o grande peixe aqui, mas por algum motivo, comecei com _siftup, me perdoe)

Acelerando _siftup

Mudei a forma de calcular parent_index porque olhei a fonte do módulo heapq e eles a usam. (veja aqui), mas não consegui ver a diferença de tempo somente com essa mudança.

Em seguida, removi a chamada para _get_parent e fiz a alteração apropriada (meio in-line, porque chamadas de função não são baratas em Python) e o novo horário é

As chamadas de função diminuíram obviamente, mas o tempo caiu apenas em torno de 70-80 milissegundos. Não é uma grande vitória (um pouco menos de 3% de aumento de velocidade). E a legibilidade não foi melhorada, então você decide se vale a pena.

Acelerando _siftdown

A primeira mudança foi para melhorar a legibilidade.

Eu transformei a atribuição ternária

Acho muito mais legível, mas provavelmente é uma questão de gosto. E para minha surpresa, quando fiz o perfil do código novamente, o resultado foi:

(Eu corri 10 vezes e sempre ganhei cerca de 80-100 milissegundos). Eu realmente não entendo porque, se alguém poderia me explicar?

Como em _siftup, eu ininei 2 chamadas da função auxiliar _get_left_child e _get_right_child e isso valeu a pena!

Isso é um aumento de 30% da linha de base.

(O que se segue é uma otimização adicional que tento explicar, mas perdi o código que escrevi para ela, vou tentar novamente mais tarde. Isso pode dar uma ideia do ganho)

Então, usando o truque heapq de comparação especializada para max e min (usando uma versão _siftdown_max e _siftup_max substituindo comparador por & gt e fazendo o mesmo para min):

Não fui mais longe nas otimizações, mas o _siftdown ainda é um peixe grande, então talvez haja espaço para mais otimizações? E pop e push talvez pudessem ser retrabalhados um pouco, mas não sei como.

Comparando meu código com o do módulo heapq, parece que eles não fornecem uma classe heapq, mas apenas um conjunto de operações que funcionam em listas? Está melhor?

Muitas implementações que vi iterar sobre os elementos usando um loop while no método siftdown para ver se chega ao fim. Em vez disso, invoco a análise da criança escolhida. Esta abordagem é melhor ou pior?

Visto que as chamadas de função são caras, o loop em vez de recorrência pode ser mais rápido. Mas acho que é melhor expresso como uma recursão.

Meu código está limpo e legível?

Para a maior parte sim! Bom código, você tem docstrings para seus métodos públicos, você respeita o PEP8, está tudo bem. Talvez você possa adicionar documentação para o método privado também? Especialmente para coisas difíceis como _siftdown e _siftup.

o ternário que mudei em _siftdown considero pessoalmente muito difícil de ler.

comparer parece um nome francês, por que não comparar? Ou eu perdi algo ou você misturou a linguagem e não deveria.

Meu teste é suficiente (para uma entrevista, digamos)?

Eu diria que não. Use um módulo para fazer testes de unidade. Eu pessoalmente gosto de pytest.

Você prefixa o nome do seu arquivo de teste por test_ e então seus métodos de teste são prefixados / sufixados por test_ / _test. Em seguida, você apenas executa o pytest na linha de comando e ele descobre os testes automaticamente, executa-os e fornece um relatório. Eu recomendo que você experimente.

Outra ótima ferramenta que você poderia ter usado é a hipótese que faz testes baseados em propriedades. Funciona bem com o pytest.

Praticamente oferece o mesmo tipo de teste que você fez em seu automatic_test, mas tem um monte de recursos interessantes adicionados e é mais curto de escrever.

Raymond Hettinger fez uma palestra muito legal sobre ferramentas para usar ao testar em um orçamento curto, ele mencionou tanto o teste quanto a hipótese, vá dar uma olhada :)

O uso de subclasses MinHeap e MaxHeap & amp é o método comparador que os distingue, uma boa abordagem para fornecer os dois tipos de heaps?

Eu acredito que sim! Mas em termos de velocidade, você deve redeclarar o siftdown e o siftup nas subclasses e substituir a instância de compare (a, b) por a & lt b ou a & gt b no código.

A última coisa é uma observação, na wikipedia, o artigo diz:

sift-up: move um nó para cima na árvore, contanto que seja necessário, usado para restaurar a condição de heap após a inserção. Chamado de & quotsift & quot porque o nó sobe na árvore até atingir o nível correto, como em uma peneira.

Sift-down: move um nó para baixo na árvore, semelhante ao sift-up usado para restaurar a condição de heap após exclusão ou substituição.

E eu acho que você usou neste contexto, mas na implementação do módulo heapq parece ter o nome invertido?

Eles usam o siftup no pop e o siftdown no push, enquanto a wikipedia nos diz para fazer o inverso. Alguém pode explicar por favor?


Algoritmo de Metaphone Duplo

O princípio do algoritmo remonta ao século passado, na verdade, ao ano de 1918 (quando o primeiro computador estava a anos de distância).

Apenas como informação secundária (caso você participe de um programa de perguntas e respostas milionário), o primeiro computador estava a 23 anos de distância

O Z3 era um computador eletromecânico alemão projetado por Konrad Zuse. Foi o primeiro computador digital programável e totalmente automático em funcionamento. O Z3 foi construído com 2.600 relés, implementando um comprimento de palavra de 22 bits que operava a uma frequência de clock de cerca de 4-5 Hz. O código do programa foi armazenado em filme perfurado. Os valores iniciais foram inseridos manualmente (Wikipedia)

Então, de volta a 1918, naquele ano, Robert C. Russell, do US Census Bureau, inventou o algoritmo Soundex, que é capaz de indexar o idioma inglês de uma forma que várias grafias do mesmo nome poderiam ser encontradas com apenas um olhar superficial.

Os imigrantes nos Estados Unidos tinham uma língua nativa que não era baseada em caracteres romanos. Para escrever seus nomes, os nomes de seus parentes ou as cidades de onde vieram, os imigrantes tiveram que dar o seu melhor palpite sobre como expressar sua linguagem simbólica em inglês. O governo dos Estados Unidos percebeu a necessidade de categorizar os nomes de cidadãos particulares de uma maneira que permitisse o agrupamento de várias grafias do mesmo nome (por exemplo, Smith e Smythe). (Leia a história completa aqui)

O algoritmo Soundex é baseado em uma categorização fonética das letras do alfabeto. Em sua patente, Russell descreve a estratégia atribuindo um valor numérico a cada categoria. Por exemplo, Johnson foi mapeado para J525, Miller para M460 etc.

O algoritmo Soundex evoluiu ao longo do tempo no contexto de eficiência e precisão e foi substituído por outros algoritmos.

Na maior parte, eles foram substituídos pelo poderoso sistema de indexação chamado Double Metaphone. O algoritmo está disponível como código aberto e sua última versão foi lançada por volta de 2009.

Felizmente, existe uma biblioteca Python disponível, que usamos em nosso programa. Escrevemos alguns pequenos métodos de invólucro em torno do algoritmo e implementamos um método de comparação.

O doublemetaphone método retorna uma tupla de chave de dois caracteres, que são uma tradução fonética da palavra passada. Nosso comparar método mostra a capacidade de classificação do algoritmo, que é bastante limitada.

Vamos fazer algumas verificações para avaliar a eficiência do algoritmo, introduzindo o test_class.py que é baseado no Python pytest estrutura.

A estrutura pytest torna mais fácil escrever pequenos testes, mas pode ser escalonada para suportar testes funcionais complexos para aplicativos e bibliotecas. (Link)

Seu uso é direto e, você pode ver a implementação da classe de teste abaixo

Os resultados dos testes são mostrados abaixo. Usamos dois nomes (A + B) e verificamos com alguns nomes alterados (A1 / A2 + B1 / B2 / B3) a eficiência do algoritmo.

  • A1 + B1 passou na verificação de compatibilidade forte. Portanto, espaços ausentes e substituições ü / ä por u / a parecem não afetar a geração de chaves metafônicas duplas
  • B2 passa a partida normal. Erros de ortografia também são cobertos pelo algoritmo
  • A2 + B3 estão falhando. A2 usa uma abreviatura de uma parte do nome, que não pode ser contada. Este comportamento que tínhamos que esperar e decidimos introduzir o algoritmo expansor de nome (veja acima). B3 falhou devido à falta de “-”. Isso foi inesperado, mas cobrimos esse comportamento com uma segunda etapa do limpador de nome.

Compreensões de lista (opcional)

Compreensão de lista é um recurso mais avançado que é bom para alguns casos, mas não é necessário para os exercícios e não é algo que você precisa aprender no início (ou seja, você pode pular esta seção). Uma compreensão de lista é uma forma compacta de escrever uma expressão que se expande para uma lista inteira. Suponha que temos uma lista nums [1, 2, 3, 4], aqui está a lista de compreensão para calcular uma lista de seus quadrados [1, 4, 9, 16]:

A sintaxe é [ expr for var in list ] -- the for var in list looks like a regular for-loop, but without the colon (:). O expr to its left is evaluated once for each element to give the values for the new list. Here is an example with strings, where each string is changed to upper case with '. ' appended:

You can add an if test to the right of the for-loop to narrow the result. The if test is evaluated for each element, including only the elements where the test is true.


Assista o vídeo: 4. Algorytmy - Sortowanie przez scalanie Merge Sort Python (Outubro 2021).