Re: [Rio-pm] Isso não deveria estar certo???
Breno++, eu precisei mover esse e-mail para pasta importantes assim como fiz com aquele ultimo que me ajudou. Dicas assim não se pode deixar perder. Lerei sim os links que me passou. E sim, a duvida foi respondida. E não recebei como bronca, nem fiquei chateado ou algo do tipo. Não sei o que dizer alem de: Obrigado. Date: Sat, 8 Dec 2012 03:40:15 -0200 From: br...@rio.pm.org To: rio-pm@pm.org Subject: Re: [Rio-pm] Isso não deveria estar certo??? Oi Aureliano, cara, antes de tudo, parabéns. O exemplo que vc colou no email mostra que vc está prestando atenção no que é dito aqui na lista. Seus códigos estão agora com strict (faltou só o 'warnings', hein?), usando autodie, open com 3 argumentos, muito bom mesmo! Agora, pra ficar perfeito, falta só uma coisa: por favor, antes de mandar dúvidas, lembre que as pessoas daqui da lista não estão sentadas aí do seu lado olhando o seu problema, nem vivendo o seu dia-a-dia para saber os motivos e objetivos do código, tampouco possuem (eu pelo menos não possuo) poder de ler mente :-) Por exemplo, quando vc pergunta algo do tipo: Monges, cade o erro??? Fica faltando o clássico grupo: o que vc está tentando fazer, de modo geral? No código específico, o que deveria estar acontecendo mas não está? Ainda no código específico, o que está de fato acontecendo em vez do que deveria? Quando, mesmo depois do Junior Moraes matar a charada, vc continua com: Mas me diz uma coisa, como editar um arquivo. A gente tem que se esforçar até pra saber que é uma pergunta, mais ainda qual é a real pergunta por trás da pergunta. Como editar um arquivo é quase tão vago quanto Preciso saber o que estou errando aqui (retirado de outra thread que vc começou). Percebe o padrão? Isso não é uma bronca. Mas, pensa comigo: se der a impressão que vc não está se esforçando nem pra fazer a pergunta, pq alguém se esforçaria pra te dar a resposta? A atividade na lista é voluntária e não remunerada, feita por pessoas com um interesse em comum (Perl) e que se dispõem a ajudar umas às outras em seu tempo livre. Por isso mesmo, se vc quer respostas melhores e mais rápidas, precisa nos ajudar a te ajudar! Por exemplo, experimente ler suas perguntas em voz alta antes de enviar o email, e veja se elas deixam realmente claro o que você está perguntando. Existe um texto muito bom sobre isso chamado Como fazer perguntas inteligentes mas também é grande e tem muitas coisas lugar-comum que você certamente já sabe. Se me permite a sugestão, vá direto nessas aqui, que são onde (eu pelo menos) sinto mais dificuldade: http://www.istf.com.br/perguntas/#writewell http://www.istf.com.br/perguntas/#beprecise http://www.istf.com.br/perguntas/#symptoms http://www.istf.com.br/perguntas/#goal http://www.istf.com.br/perguntas/#examples Não estou falando isso pra vc ficar chateado, pelo contrário! Estou só tentando te ajudar a nos ajudar, e assim tirar maior proveito das listas e melhorar cada vez mais. Os parágrafos acima são uma leitura super rápida, pense como um investimento: vc vai gastar menos de 5 minutos pra ler (e está traduzido em português!) e se prestar atenção nesses pontos, tenho certeza que daqui pra frente você vai conseguir respostas muito mais rapidamente nessa e em qualquer outra lista! Dito isso, deixa eu tentar te ajudar. Eu *acho*, depois de perder um bom tempo olhando pro seu exemplo, que a sua pergunta é: Pessoal, como eu faço pra abrir o mesmo arquivo tanto para leitura quanto para escrita? ou Pessoal, como eu faço para ler e escrever no mesmo arquivo, ao mesmo tempo? Se for isso mesmo, é uma pergunta super comum. E, como a maioria das coisas em Perl, há mais de uma maneira de se fazer :) Digamos, para efeito de exemplo, que você queira passar o nome de um arquivo como parâmetro para o seu programa. O arquivo tem o formato: --8--- blablabla ACTGAACAGTAGCTACTGACTCGTACGCTCGTAGC lalalala CAGCTGATCGATCGTAGCATGCTACG --8--- E o que você quer é transformar esse arquivo em algo como: --8--- contig0 ACTGAACAGTAGCTACTGACTCGTACGCTCGTAGC contig1 CAGCTGATCGATCGTAGCATGCTACG --8--- Claro, não só duas linhas e sim centenas, mas acho que deu pra entender. Solução 1 (one-liner) perl -i -pe 'BEGIN { $i = 0 } $i++ if s{^.+$}{contig$i}' arquivo.txt Essa solução usa perl como ferramenta para transformação de arquivos in place. O -pe executa o código entre aspas para cada linha do arquivo passado, imprimindo o que estiver em $_ no final do processamento de cada linha. O código em si é simples: substitua ^.+$ (início de linha seguido de seguido de qualquer coisa, seguido do fim da linha) pela string contig$i, onde $i é um número que começa com zero (por isso o BEGIN { $i = 0 }, senão $i começa vazio, e a primeira linha vira apenas contig em vez de contig0). Sempre que conseguir fazer essa substituição (ou
Re: [Rio-pm] Isso não deveria estar certo???
Breno, so uma duvida, antigamente eu usava muito arquivos temporario, eu deixei de usar pois achava que perdia muito em performance. Você acha que eu perco muito em performance usando a solução 4 no lugar das outras soluções? From: guedes_1...@hotmail.com To: rio-pm@pm.org Date: Sat, 8 Dec 2012 10:13:53 + Subject: Re: [Rio-pm] Isso não deveria estar certo??? Breno++, eu precisei mover esse e-mail para pasta importantes assim como fiz com aquele ultimo que me ajudou. Dicas assim não se pode deixar perder. Lerei sim os links que me passou. E sim, a duvida foi respondida. E não recebei como bronca, nem fiquei chateado ou algo do tipo. Não sei o que dizer alem de: Obrigado. Date: Sat, 8 Dec 2012 03:40:15 -0200 From: br...@rio.pm.org To: rio-pm@pm.org Subject: Re: [Rio-pm] Isso não deveria estar certo??? Oi Aureliano, cara, antes de tudo, parabéns. O exemplo que vc colou no email mostra que vc está prestando atenção no que é dito aqui na lista. Seus códigos estão agora com strict (faltou só o 'warnings', hein?), usando autodie, open com 3 argumentos, muito bom mesmo! Agora, pra ficar perfeito, falta só uma coisa: por favor, antes de mandar dúvidas, lembre que as pessoas daqui da lista não estão sentadas aí do seu lado olhando o seu problema, nem vivendo o seu dia-a-dia para saber os motivos e objetivos do código, tampouco possuem (eu pelo menos não possuo) poder de ler mente :-) Por exemplo, quando vc pergunta algo do tipo: Monges, cade o erro??? Fica faltando o clássico grupo: o que vc está tentando fazer, de modo geral? No código específico, o que deveria estar acontecendo mas não está? Ainda no código específico, o que está de fato acontecendo em vez do que deveria? Quando, mesmo depois do Junior Moraes matar a charada, vc continua com: Mas me diz uma coisa, como editar um arquivo. A gente tem que se esforçar até pra saber que é uma pergunta, mais ainda qual é a real pergunta por trás da pergunta. Como editar um arquivo é quase tão vago quanto Preciso saber o que estou errando aqui (retirado de outra thread que vc começou). Percebe o padrão? Isso não é uma bronca. Mas, pensa comigo: se der a impressão que vc não está se esforçando nem pra fazer a pergunta, pq alguém se esforçaria pra te dar a resposta? A atividade na lista é voluntária e não remunerada, feita por pessoas com um interesse em comum (Perl) e que se dispõem a ajudar umas às outras em seu tempo livre. Por isso mesmo, se vc quer respostas melhores e mais rápidas, precisa nos ajudar a te ajudar! Por exemplo, experimente ler suas perguntas em voz alta antes de enviar o email, e veja se elas deixam realmente claro o que você está perguntando. Existe um texto muito bom sobre isso chamado Como fazer perguntas inteligentes mas também é grande e tem muitas coisas lugar-comum que você certamente já sabe. Se me permite a sugestão, vá direto nessas aqui, que são onde (eu pelo menos) sinto mais dificuldade: http://www.istf.com.br/perguntas/#writewell http://www.istf.com.br/perguntas/#beprecise http://www.istf.com.br/perguntas/#symptoms http://www.istf.com.br/perguntas/#goal http://www.istf.com.br/perguntas/#examples Não estou falando isso pra vc ficar chateado, pelo contrário! Estou só tentando te ajudar a nos ajudar, e assim tirar maior proveito das listas e melhorar cada vez mais. Os parágrafos acima são uma leitura super rápida, pense como um investimento: vc vai gastar menos de 5 minutos pra ler (e está traduzido em português!) e se prestar atenção nesses pontos, tenho certeza que daqui pra frente você vai conseguir respostas muito mais rapidamente nessa e em qualquer outra lista! Dito isso, deixa eu tentar te ajudar. Eu *acho*, depois de perder um bom tempo olhando pro seu exemplo, que a sua pergunta é: Pessoal, como eu faço pra abrir o mesmo arquivo tanto para leitura quanto para escrita? ou Pessoal, como eu faço para ler e escrever no mesmo arquivo, ao mesmo tempo? Se for isso mesmo, é uma pergunta super comum. E, como a maioria das coisas em Perl, há mais de uma maneira de se fazer :) Digamos, para efeito de exemplo, que você queira passar o nome de um arquivo como parâmetro para o seu programa. O arquivo tem o formato: --8--- blablabla ACTGAACAGTAGCTACTGACTCGTACGCTCGTAGC lalalala CAGCTGATCGATCGTAGCATGCTACG --8--- E o que você quer é transformar esse arquivo em algo como: --8--- contig0 ACTGAACAGTAGCTACTGACTCGTACGCTCGTAGC contig1 CAGCTGATCGATCGTAGCATGCTACG --8--- Claro, não só duas linhas e sim centenas, mas acho que deu pra entender. Solução 1 (one-liner) perl -i -pe 'BEGIN { $i = 0 } $i++ if s{^.+$}{contig$i}' arquivo.txt Essa solução usa perl como ferramenta para transformação de arquivos in place. O -pe executa o código entre aspas para cada linha do arquivo passado, imprimindo o que estiver em $_ no final do
Re: [Rio-pm] Isso não deveria estar certo???
2012/12/9 Aureliano Guedes guedes_1...@hotmail.com: Breno, so uma duvida, antigamente eu usava muito arquivos temporario, eu deixei de usar pois achava que perdia muito em performance. Você acha que eu perco muito em performance usando a solução 4 no lugar das outras soluções? Resposta brevíssima: não importa. Pronto. Pode parar de ler aqui. É sério. Se, por alguma curiosidade mórbida, vc quiser mais detalhes, continue lendo :) Como a maioria das coisas do mundo, depende. Se você tiver RAM infinita, manter tudo em memória é sempre muito mais rápido do que fazer acessos ao disco. Para saber mais: https://en.wikipedia.org/wiki/Space-time_tradeoff No entanto, há casos em que você *quer* armazenar dados em arquivos temporários, não só por questões de memória, mas também para ter estados intermediários em sua execução. Ou quando, como no exemplo anterior, vc quer transformar um arquivo em outro. Afinal, pense comigo: se vc vai ler um arquivo de entrada e escrever num arquivo de saída, pq precisa que seja o mesmo arquivo? Preservar o arquivo original pode te ajudar não só na simplicidade do código como nos casos em que você quer validar os resultados repetindo a execução, ou depurar seu programa caso algo estranho esteja acontecendo. Sem o original intacto, como recuperá-lo? Você provavelmente está guardando cópia do arquivo original em algum lugar (por esses mesmos motivos) então pq não oficializar a coisa e gravar a saída processada em outro arquivo (que portanto deixa de ser temporário)? Vejamos as operações envolvidas no problema. Sem arquivos temporário, temos os seguintes passos: 1) ler o arquivo todo do disco para memória 2) processar os dados 3) voltar a posição do handle para o início do arquivo 4) escrever o arquivo no disco 5) truncar o restante Já com arquivos temporários, temos: 1) ler o arquivo do disco para memória 2) processar os dados 3) escrever o arquivo novo no disco 4) renomear arquivo no disco para substituir original (se não for usar) Otimizações à parte, o processo em si é bastante parecido, com uma ação de leitura e outra de escrita (ok, duas se rolar o rename, mas não é lá uma grande operação de E/S), então não deve fazer lá grandes diferenças em termos de desempenho. Antes de continuar, esqueci de colocar na resposta anterior uma outra solução entre a 4 e a 5, vamos chamá-la de 4.5: --8--- #!/usr/bin/env perl use strict; use warnings; use autodie; my $nome_original = 'arquivo.txt'; open my $orig_fh, '', $nome_original; my @linhas; my $i = 0; while ( my $linha = $orig_fh ) { if ($linha =~ s/^.+$/contig$i/ ) { $i++; } } continue { push @linhas, $linha; } close $orig_fh; open $orig_fh, '', $nome_original; print $orig_fh @linhas; close $orig_fh; --8--- Essa solução tem duas diferenças em relação à 4. Aqui, estamos acumulando os dados processados em memória (na variável @linhas) e, após o processamento, reabrimos o mesmo arquivo, só que para escrita. Continuamos com o perigo da manipulação sem locking, mas eliminamos a necessidade do arquivo temporário. Particularmente, continuo preferindo a solução 4, pelos mesmos motivos de antes. Uma nota sobre desempenho: quando o único fator a ser considerado é desempenho, a melhor solução é escrever em Assembly. Mais ainda: quando o único fator a ser considerado for desempenho, ou você está desenvolvendo algo muito específico *mesmo* ou, em geral, há uma chance muito grande de algo estar fundamentalmente errado no seu raciocínio. Esse erro é conhecido como otimização prematura. Nas palavras de Donald Knuth: Programadores desperdiçam um tempo enorme pensando sobre, ou se preocupando com, a velocidade de partes não críticas de seus programas, e essas tentativas de melhorar a eficiência na verdade acabam tendo um forte impacto negativo quando depuração e manutenção são consideradas. Precisamos esquecer eficiências menores em, digamos, 97% do tempo: otimização prematura é a raiz de todo o mal. No entanto não podemos deixar passar a oportunidade naqueles 3% crítico. Sempre que pensar em desempenho, lembre-se dessas sábias palavras. (Para saber mais sobre a questão: http://c2.com/cgi/wiki?PrematureOptimization) Para o seu caso, isso significa: programe SEMPRE com foco em legibilidade, testabilidade e manutenção. Preocupe-se com desempenho SOMENTE depois que isso se tornar um problema. Tem pessoas que se prendem a benchmarks do tipo: a função X me deixa fazer 32000 operações por segundo, enquanto que a função Y me deixa fazer em 27000 operações por segundo, então é FATO que devemos escolher a função X, pois é mais rápida, certo? Errado. Isso não deveria ser critério de desempate, vc deveria escolher a função que for mais clara e fácil de testar e de dar manutenção depois (extender, reduzir, alterar, acoplar, etc). Afinal, se você faz mais de 1000 operações por segundo com essa função, já está usando bastante. Mas repare que, mesmo que você faça 25000 operações *por segundo*, ambas as