Opa, obrigado pela ajuda e pelas preciosas dicas. - Não achei uma função no List::MoreUtils que fizesse o mesmo que o dups do Array::Uniq, tem alguma função no List::MoreUtils que crie um terceiro array apenas com itens que outros dois ou mais arrays tem em igual?
- Particularmente não vi vantagem em usar o Path::Class, para meu caso qual seria a vantagem? - Quanto a criar um modulo fazendo o que as subs fazem, depois vou pensar nessa hipotese, mais um modulo para o BioPerl não faz mal. - Quanto ao que você falou no item 11: - Continuei usando barewords pois não deu certo usando strings, por algum motivo que não sei por que? (Afinal qual o problema das barewords?) "11) No seu código você abre os arquivos 'hybrid.txt' e 'miranda.txt' duas vezes para leitura. Isso normalmente significa que você poderia ter colocado tudo numa estrutura de fácil acesso e manipulação, e lido o arquivo apenas uma vez (operações de E/S costumam ser bem mais pesadas do que manipulação em memória). Dica: sempre que tiver mais de um while() ou foreach() varrendo a mesma estrutura para ler dados, é bem possível que você possa otimizar e deixar mais claro seu algoritmo fazendo a varredura apenas uma vez." Isso me preocupou, veja bem, não consegui pensar em uma forma de varrer o arquivo fazendo o que preciso apenas em um laço. parsin_h e parsin_m extraem um valor que são gravados em array, @inh e @inm respectivamente, depois um terceiro array (@in) é criado apenas com os valores que @inh e @inm tem em comum. Os valores de @in são a referencia de "o que" eu quero extrair dos arquivos hybrid.txt e miranda.txt. Realmente o excesso de operações I/O pesam mas infelizmente não estou conseguindo fugir disso, e desempenho na bioinformatica é importante. Pesso ajuda para solucionar esse mistério tambem. Outro problema é que o output esta feio e ainda o $/ esta sendo omitido. link do script com as devidas alterações -> http://pastebin.com/DNuiLUHG link do miranda.txt ->http://pastebin.com/qiYavtUe link do hybrid.txt -> http://pastebin.com/9v6WFUT7 Agora para exclarecer os arquivos: Miranda pode ter dois formatos: Read Sequence:hsa-miR-4448 MIMAT0018967 Homo sapiens miR-4448(20 nt) Read Sequence:01010101 (582 nt) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Performing Scan: hsa-miR-4448 vs 01010101 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Score for this Scan: No Hits Found above Threshold Complete ou Read Sequence:hsa-miR-4701-3p MIMAT0019799 Homo sapiens miR-4701-3p(20 nt) Read Sequence:01010101 (582 nt) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Performing Scan: hsa-miR-4701-3p vs 01010101 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Forward: Score: 140.000000 Q:2 to 9 R:205 to 224 Align Len (7) (100.00%) (100.00%) Query: 3' ugugguguggguAGUGGGUa 5' ||||||| Ref: 5' ccatgggggagcTCACCCAc 3' Energy: -12.410000 kCal/Mol Scores for this hit: >hsa-miR-4701-3p 01010101 140.00 -12.41 2 9 205 224 7 >100.00% 100.00% Score for this Scan: Seq1,Seq2,Tot Score,Tot Energy,Max Score,Max Energy,Strand,Len1,Len2,Positions >>hsa-miR-4701-3p 01010101 140.00 -12.41 140.00 -12.41 1524 >> 20 582 205 Complete A diferença é que em um não houve analise e em outro houve, o valor que esta em negrito é o que eu estou procurando. Hybrid so tem o seguinte formato: target: 01010101 length: 581 miRNA : hsa-miR-15a length: 22 mfe: -24.4 kcal/mol p-value: 0.334111 position 244 target 5' C UCUCCUGUGGUCUCU G U 3' CACA GACCA GUGCUGUU GUGU UUGGU CACGACGA miRNA 3' AAUA U 5' E o valor que me importa é o que esta em negrito. From: bruno.b...@gmail.com Date: Wed, 21 Nov 2012 14:21:18 -0200 To: rio-pm@pm.org Subject: Re: [Rio-pm] Comparação de arquivos breno++ 2012/11/21 breno <br...@rio.pm.org> Oi Aureliano, acho que o que o Tiago quis dizer é "o que deveria estar acontecendo mas não está, e o que está acontecendo em vez disso?" Assumindo que não há problema na lógica e o que está tentando resolver são os warnings que colou no final do paste, a resposta está na recomendação número 5 abaixo. Agora, algumas dicas gerais sobre o código que você colou: 1) a solução canônica para manipulação de listas são os módulos List::Util, List::MoreUtils e List::AllUtils (que agrega as funções de ambos). No List::MoreUtils (e, consequentemente, no List::AllUtils) há a função uniq() que faz o mesmo que o Array::Uniq. Então, a menos que você tenha um excelente motivo para usar o Array::Uniq, recomendo trocar para o List::MoreUtils. 2) Evite open() com apenas dois argumentos. Evite open() com barewords em vez de variáveis. Por mais que você saiba o que está fazendo, procure sempre manter a sintaxe: open my $fh, '<', $nome_do_arquivo or die "erro abrindo arquivo $nome_do_arquivo para leitura: $!"; para leitura, ou: open my $fh, '>' $nome_do_arquivo or die "erro abrindo arquivo $nome_do_arquivo para escrita: $!"; Se quiser omitir o "or die..." basta colocar "use autodie;" no início do seu programa. Mais ainda, pode usar módulos como Path::Class que já manipulam o arquivo para você: use Path::Class; my $fh = file( 'meuarquivo.txt' )->openr(); # ou openw() para escrever Veja mais detalhes em https://metacpan.org/module/Path::Class::File 3) Ao colar um exemplo, certifique-se que ele está limpo. A linha 75, por exemplo, tenta abrir um arquivo para escrita: open SL, ">:raw", "sl.txt" or die $!; mas não faz nada com ele. 4) Evite usar termos como new() e $self quando seu código não for orientado a objetos. Essas não são palavras reservadas em Perl, mas convenciona-se que new() constrói objetos e $self os referencia. Usar esses nomes com outros objetivos confunde :) 5) Evite "ações à distância" (https://en.wikipedia.org/wiki/Action_at_a_distance_%28computer_programming%29). A variável especial $_, por exemplo, é global quando seu código espera que ela seja local. Repare que você está consumindo seus dados usando $_ implicitamente em 3 momentos distintos e concorrentes: foreach (@in) { # $_ definido como o valor atual em @in print find_m($_), find_h($_); } sub find_m { my $self = shift; while (<INM2>) { # $_ redefinido, agora para a linha atual ... } # ao final do bloco, $_ estará como undef (pois o arquivo acabou) } idem para a sub find_h. A solução? Bom, a partir do Perl 5.10 (lançado a quase 5 anos atrás) é possível usar uma versão léxica do $_ ao declará-lo no bloco com 'my'. É possível também restaurar o valor global de $_ no escopo atual usando 'our $_', mas não é isso o que você quer. Para deixar seu código claro e evitar efeitos colaterais, sugiro sempre "dar nomes aos bois" e nomear suas variáveis de loop. Por exemplo, trocar: foreach (@in) por foreach my $elemento (@in) já teria resolvido seu problema (assumindo, claro, que agora você estaria passando "$elemento" para as funções, em vez de "$_"). Recomendo mudar também no while() dentro das subs. Outro problema de 'action at a distance' no seu código, menos grave mas ainda assim importante, é que você está usando nas funções find_m e find_h handles abertos em outro bloco, referenciados pela mesma bareword. Fiquei sem entender se a sua lógica considera o consumo linear do arquivo (para cada ocorrencia em @in, os arquivos hybrid.txt e miranda.txt estarão mais próximos do final) ou se isso é um bug. 6) Não utilize 'our' quando não precisar - e você não precisa nesse exemplo. Para saber mais sobre origem e diferenças entre my, our, local e etc, recomendo a palestra do Util => http://youtu.be/Ton-5tvDQiE 7) Não utilize variáveis globais quando não precisar - e você não precisa nesse exemplo. 8) Não agrupe elementos em expressões regulares se não for utilizar. Nas regexes das subs parsin_m() e find_m() você tem dois grupos (parenteses () dentro da regex) e só usa o $1. 9) Não manipule $/ diretamente. Se realmente precisar, faça "local $/ = ..." dentro do bloco. 10) Se as saídas de 'hybrid' e 'miranda' são sempre nesse formato, crie um parser separadamente para elas e utilize em seu código. Deixa tudo mais limpo e de quebra você ainda pode colocar no CPAN e ajudar outras pessoas :) 11) No seu código você abre os arquivos 'hybrid.txt' e 'miranda.txt' duas vezes para leitura. Isso normalmente significa que você poderia ter colocado tudo numa estrutura de fácil acesso e manipulação, e lido o arquivo apenas uma vez (operações de E/S costumam ser bem mais pesadas do que manipulação em memória). Dica: sempre que tiver mais de um while() ou foreach() varrendo a mesma estrutura para ler dados, é bem possível que você possa otimizar e deixar mais claro seu algoritmo fazendo a varredura apenas uma vez. 12) Sempre que o seu programa estiver fazendo algo estranho, tente diminuir ao máximo a superfície de erro, e inspecionar o valor das variáveis. No seu caso, por exemplo, o interpretador disse que o problema estava quando a sua linha de print chamava as funções: print OUT ("#" x 20 , find_m($_) , "\n" , find_h($_) , "#" x 20 , "\n"); então o primeiro passo seria desmembrar, retirando tudo que é inútil ( '#' x 20 ) e colocando cada chamada em uma linha diferente, para tentar isolar o erro. Outra, claro, é imprimir direto na tela em vez de em arquivo: print find_m($_); print "\n"; print find_h($_); Se a sua variável for uma estrutura maior em vez de apenas uma string, soluções como o Data::Printer podem te ajudar também. Espero ter ajudado! []s -b _______________________________________________ Rio-pm mailing list Rio-pm@pm.org http://mail.pm.org/mailman/listinfo/rio-pm -- Bruno C. Buss http://www.brunobuss.net _______________________________________________ Rio-pm mailing list Rio-pm@pm.org http://mail.pm.org/mailman/listinfo/rio-pm
_______________________________________________ Rio-pm mailing list Rio-pm@pm.org http://mail.pm.org/mailman/listinfo/rio-pm