Mostrando postagens com marcador python. Mostrar todas as postagens
Mostrando postagens com marcador python. Mostrar todas as postagens

sábado, 29 de setembro de 2012

Aprendendo Bionformática com Rosalind


Rosalind

Rosalind é um site que propõe a aprendizagem de bioinformática através da solução de problemas computacionais com diversos graus de dificuldade extraídos de problemas reais. Rosalind é uma plataforma de aprendizagem de bioinformática através de solução de problemas.

Rosalind é um projeto inspirado por outros projetos como Project Euler e  Google Code Jam .

Cada problema introduz novos termos da área de bioinformática. O glossário de todos os problemas é bastante extenso:
http://rosalind.info/glossary/

Problem 1

A string is simply an ordered collection of symbols selected from some alphabet and formed into a word; the length of a string is the number of symbols that it contains.
An example of an DNA string (whose alphabet contains the symbols A, C, G, and T) is ATGCTTCAGAAAGGTCTTACG.
Given: A DNA string s of length at most 1000 nucleotides.
Return: Four integers corresponding to the number of times that the symbols A, C, G, and T occur in s.

Sample Dataset

AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC

Sample Output

20 12 17 21


Você pode resolver este desafio utilizando qualquer linguagem que você queira uma vez que você precisa apenas enviar a resposta. Você pode aproveitar para a aprender uma nova linguagem de programação e/ou utilizar uma linguagem mais adequada para resolver estes problemas. Eu sugiro a linguagem Python.


s = raw_input()
print "%d %d %d %d" % ( s.count('A') , s.count('C'), s.count('G'), s.count('T')






quarta-feira, 29 de agosto de 2012

As próximas cinco linguagens para você aprender... e por quê?

O título desse post é o mesmo de uma palestra ministrada pelo professor Fernando Castor do CIN-UFPE. Na palestra, ele aborda toda a problemática de comparar as diversas linguagens de programação. Dizer qual é a melhor linguagem de programação ou mais usada não são perguntas fáceis de responder. Para definir as próximas cinco linguagens que você deve aprender, o palestrante considerou os seguintes aspectos:


  1. Primeira linguagem de programacão para aprender
  2. Linguagem Pós-Java
  3. Programacão multi-núcleo e sistemas confiáveis
  4. Desenvolvimento para a Web
  5. Software de baixo nível e de alto desempenho

Primeira linguagem de programacão para aprender
Escolhida: Python
Outras: Lua, Groovy e Ruby
Motivos:
  • Sintaxe amigável
  • Dinamicamente tipicada
  • Multiparadigma
  • Muito popular na prática
  • Usada como primeira linguagem em v ários cursos de computa cão
O grande trunfo da linguagem Python é a sua legibilidade. Além disso,a linguagem Python tem estrutura de dados nativas poderosas e otimizadas (lista, hash, string).  Uma característica interessante do Python é que muitos operadores funcionam de maneira similar em todas as sequências. Um bom exemplo de ortogonalidade dos
operadores.

STRING
LISTA
TUPLA

 Operação        
 Operação        
 Operação        
interpretação
  s1 + s2          
L1 + L2      
t1 + t2    
Concatenação
  s1 * 3         
L1 * 3       
t1 * 3                 
Repetição
  s1[i]            
L1[i]        
t1[i],t2[i][j]
Indice
  s1[i:j]          
L1[i:j]      
t1[i:j]        
Fatia (slice)
  len(s1)          
len(L1)      
len(t1)        
Tamanho(length)
 for x in s1      
for x in L1  
for x in t1    
Iteração
  'm' in s1        
3 in L1      
for 3 in t1  
(Pertinência)Membership

Essa caracteristica facilita o aprendizado e faz com que os chutes geralmente sejam certos.

A filosofia do Python
Bonito é melhor que feio.
Explícito é melhor que implícito.
Simples é melhor que complexo.
Complexo é melhor que complicado.
Plano é melhor que aninhado.
Esparso é melhor que denso.
Legibilidade conta.
Casos especiais não são especiais o bastante para se quebrar as regras.
Embora a simplicidade supere o purismo.
Erros nunca deveriam passar silenciosamente.
A menos que explicitamente silenciados.
Ao encarar a ambiguidade, recuse a tentação de adivinhar.
Deveria haver uma – e preferencialmente apenas uma – maneira óbvia de se fazer isto.
Embora aquela maneira possa não ser óbvia à primeira vista se você não for holandês.
Agora é melhor que nunca.
Embora nunca, seja muitas vezes melhor que pra já.
Se a implementação é difícil de explicar, é uma má idéia.
Se a implementação é fácil de explicar, pode ser uma boa idéia.
Namespaces são uma idéia estupenda – vamos fazer mais deles!


Referências:

Linguagem Pós-Java
Linguagem Escolhida: Scala
A idéia é escolher uma linguagem que utilize a plataforma Java mas não utilize a linguagem Java. Mais ou menos como acontece com a plataforma .NET que suporta várias linguagens. 
  • Compatibilidade retroativa com Java: roda na JVM
  • Menos verborrágica
  • Inclui inferência de tipos!
  • Imperativa, OO, funcional e concorrente.
Programa cão multi-núcleo e sistemas confiáveis
Escolhida: Erlang
Motivos:
  • Filosofia Let It Crash
  • Puramente funcional e sem estado compartilhado
  • Processos leves  unidades nas de quebra de trabalho
  • Concorrência e distribuicão são inerentes a linguagem e impossível construir sistemas não-triviais ignorando isso
Desenvolvimento para a Web
Premissas: 
  • JavaScript é a linguagem Assembly para web
  • JavaScript tem várias falhas.
  • Entender o escopo de JavaScript é complicado
Escolhida: DART

Motivos:
  • Menos caos
  • sem protótipos, objeto global ou atributos adicionados dinamicamente
  • Possibilidade de usar anotacões de tipo
  • Escopos intuitivos, baseados em blocos
  • Compilável para JavaScript
  • Desenvolvida pelo Google


Links:

Software de baixo nível e de alto desempenho

Premissas:
  • a linguagem permite ter acesso direto a memória RAM
  • a linguagem permite  gerenciamento memória manualmente
  • a linguagem permite  guardar valores de variáveis explicitamente em registradores
  • a linguagem produz código extremamente e ficiente
  • a linguagem faz isso tudo  de forma portável?
Escolhida: C

Motivos:
  • Porque permite tudo mencionado nas premissas
  • Porque é muito menos complexa que C++
  • Porque Assembly s ó é uma opção quando e a unica opção
  • Gerenciamento de memória manual
  • Tipificação fraca
  • Manipulação de ponteiros é fundamental mesmo para as operações mais básicas, complexa e insegura
  • ausência de suporte decente a programação paralela
Até as características negativa da linguagem C fornecem lições importantes. Leia esse artigo:

Flamewar:
Nilo Araújo: o texto fala que C fornece a opcao de guardar valores diretamente em registradores. Ate onde eu sei, entretanto, é que voce pode PEDIR isso, mas o sistema pode nao atender se nao quiser..

Resposta:

A palavra reservada register é modificador que avisa para o compilador que ele deve usar o registrador mesmo quando a opção de otimização está desabilitada. Quando a opção de otimização está habilitada, o compilador ignora o seu pedido e faz o que ele quer. 
http://tigcc.ticalc.org/doc/keywords.html#register

GNU C tem uma extensão que permite a manipulação explícita da seguinte maneira: 

register int *foo asm ("a3");

Observe que esta notação é cpu-dependente , você precisa saber o nome do registrador.

http://tigcc.ticalc.org/doc/gnuexts.html#SEC98


Links:
http://meiobit.com/107326/no-o-sistema-operacional-da-curiosity-no-linux-mas-voc-provavelmente-j-o-usou/

sexta-feira, 13 de abril de 2012

List comprehension and Generator Expressions

Python language has several interesting features. In this post, let's talk about two features: List comprehension and generator expressions.

List comprehension is a syntactic construct that allows creation of lists very similar to the way of defining sets in set theory. In set theory, we can define a set through a property that characterizes its  elements .
S = {2x | x Î N and 1 <= x <= 3}

In Python, we can define a list with the same elements of S as follows:
S = [2 * x for x in range (1,4)]

This way of defining the list allows you to implement algorithms more clear and direct. The quicksort algorithm can be defined as follows:

def qsort (list):
     if list == []: 
         return []
     else:
         pivot = list [0]
         lesser = qsort ([x for x in list [1:] if x 
         Greater = qsort ([x for x in list [1:] if x> = pivot])
         return lesser + [pivot] + Greater


From a list, we can create two lists: lesser and greater. The lesser list is formed by  elements smaller than the pivot .  The last list is formed by elements greater than the pivot. These two lists are sorted recursively and then are joined again. 


The version dynamic choice of pivot can be easily set as follows: 

from random import randrange
 qsortrand def (list):
     if list == []: 
         return []
     else:
         pivot = list. pop (randrange (len (list)))
         lesser qsortrand = ([l for l in list if l 
         Greater qsortrand = ([l for l in list if l> = pivot])
         return lesser + [pivot] + Greater

Code: http://ideone.com/5mtoj 
import random
 import time
 quick import from qsort, qsortrand

 numElements = int (raw_input ("Enter array size:")) 
 testlist = random. sample (xrange (999999999), numElements)
 q is in qsort, qsortrand:
     print "# elements:% d"% numElements
     testlist list = [:]
     start = time. clock ()
     result = q (list)
     elapsed = (time. clock () - start)
     print "% .3 f secs"% (elapsed)


 
Test Results: 

100
1000
10000
qsort
0001 secs
0008 secs
0043 secs
qsortrand
0001 secs
0011 secs
0052 secs




Although it is a good idea to use list comprehension have some problems with performance and efficient use of memory. So, the Python language introduced the concept of generators and generator expressions.


In some cases, experience shows that need not have all the list created in memory. We just need to know to iterate over the elements one by one. To perform the sum of all numbers in a certain range does not need the entire range created a priori.Consider the following example: 

import time
 start = time. clock ()
 # List using compreenhension
 print sum ([x for x in range (1, 1000000)]) 
 elapsed = (time. clock () - start)
 print "% .3 f secs"% (elapsed)

start = time. clock ()
 # Generator expression using
 print sum (x for x in range (1, 1000000))
 elapsed = (time. clock () - start)
 print "% .3 f secs"% (elapsed)

Result: 
499999500000 
0340 secs 
499999500000 
0224 secs 

The semantics of a generator expression is that the elements are generated when needed. 

  = g (x for x in range (1, 1000000))
 print g. next () 
 print g. next ()
 print g. next ()

 Output
 1
 2
 3

The semantics of an  generating  expression is equivalent to  anonymous  generating  function  using  yield. 

def __ f (exp):
     for x in exp:
         yield x
        
 __ g = f (iter (range (1, 1000000)))
 print g. next ()
 print g. next ()
 print g. next ()

 Sa t of 
 A
 2
 3

An interesting example is to use the generating expression to make a program that displays the Fibonacci numbers less than 100. 

def fib ():
     a, b = 0, 1
     while 1:
         yield b
         a, b = b, a + b

 for x in fib ():
     if x <100:
         print x

sexta-feira, 30 de março de 2012

List comprehension e Generator Expressions

A linguagem Python possui diversos recursos interessantes. Nesse post, vamos falar de dois recursos: List comprehension e Generator Expressions.

List comprehension é uma construção sintática que permite a criação de lista muito parecida com a forma de definir conjuntos na teoria dos conjuntos. Na teoria de conjuntos, podemos definir um conjunto através de uma propriedade que caracteriza os seus elementos.
S = {2x | x Î N e 1<=x<=3}

Na linguagem Python, podemos definir uma lista com os mesmo elementos de S da seguinte maneira:
S = [2*x for x in range(1,4)]

Essa maneira de definir lista permite implementar algoritmos de maneira mais clara e direta. O algoritmo quicksort pode ser definido da seguinte maneira:

def qsort(list):
    if list == []: 
        return []
    else:
        pivot = list[0]
        lesser = qsort([x for x in list[1:] if x < pivot])
        greater = qsort([x for x in list[1:] if x >= pivot])
        return lesser + [pivot] + greater


A partir de uma lista, podemos criar duas listas: lesser e greater. A lista lesser é formada pelos elementos menores que o pivô e a lista greater formada pelos elementos maiores que o pivô. Essas duas listas são ordenadas recursivamente e depois são unidas novamente.


A versão com escolha do pivô dinâmica pode ser definida facilmente da seguinte maneira:

from random import randrange 
def qsortrand(list):
    if list == []: 
        return []
    else:
        pivot = list.pop(randrange(len(list)))
        lesser = qsortrand([l for l in list if l < pivot])
        greater = qsortrand([l for l in list if l >= pivot])
        return lesser + [pivot] + greater

Código: http://ideone.com/5mtoj

import random
import time
from quick import qsort, qsortrand

numElements = int( raw_input("Entre com o tamanho do vetor:") ) 
testlist = random.sample(xrange(999999999), numElements)
for q in qsort, qsortrand:
    print "# elements: %d"%numElements
    list = testlist[:]
    start = time.clock()
    result = q(list)
    elapsed = (time.clock() - start)
    print "%.3f secs"%(elapsed)


Resultados dos Testes:


100
1000
10000
qsort
0.001 secs
0.008 secs
0.043 secs
qsortrand
0.001 secs
0.011 secs
0.052 secs




Apesar de ser uma boa ideia, o uso de list comprehension têm alguns problemas relacionados com perfomance e uso eficiente de memória. Então, a linguagem Python introduziu o conceito de expressões geradoras e geradores.


Em alguns casos, a experiência mostra que não precisamos ter toda a lista criada na memória. Precisamos apenas saber iterar sobre os elementos um por um. Para realizar a soma de todos os números em um certo intervalo não precisamos de todo o intervalo criado a priori. Considere o seguinte exemplo:

import time
start = time.clock()
#usando list compreenhension
print sum( [x for x in range(1,1000000)] ) 
elapsed = (time.clock() - start)
print "%.3f secs"%(elapsed)

start = time.clock()
#usando generator expression
print sum( x for x in range(1,1000000) )
elapsed = (time.clock() - start)
print "%.3f secs"%(elapsed)

Resultado:
499999500000
0.340 secs
499999500000
0.224 secs

A semântica de uma generator expression é que os elementos são gerados quando necessários.
g = ( x for x in range(1,1000000) )
print g.next() 
print g.next()
print g.next()

Saída
1
2
3

A semântica de uma expressão geradora é equivalente a uma função geradora anônima usando yield.

def __f(exp):
    for x in exp:
        yield x
        
g = __f(iter(range(1,1000000)))
print g.next()
print g.next()
print g.next()

Saída 
1
2
3

Um exemplo interessante é utilizar a expressão geradora para fazer um programa que exibe os números de Fibonacci menores que 100.

def fib():
    a,b = 0,1
    while 1:
        yield b
        a,b = b,a+b

for x in fib():
    if x < 100:
        print x