sábado, 19 de outubro de 2013

Problema 3.10

Vamos resolver o problema 3.10 do livro que nos pede para gerar uma cadeia de ADN. O único argumento/parâmetro formal é o tamanho da sequência pretendido. Trata-se de um exercício muito fácil, mas que nos pode dar alguns ensinamentos.
A ideia da solução passa por repetir tantas vezes quantas o tamanho da sequência a escolha aleatória de uma das bases presentes na cadeia de ADN, de entre as quatro possíveis (Adenina (A), Citosina (C), Guanina (G) e Timina (T). Os resultados vão sendo acumulados. Daí a solução.
01.import random
02. 
03.def gera_adn(tam):
04.    """Gera uma cadeia de ADN de tamanho tam. Padrão ciclo-acumulador"""
05.    adn =''
06.    for i in range(tam):
07.        base = random.choice('TACG')
08.        adn = adn + base
09.    return adn
Baseia-se esta solução no padrão ciclo (neste caso ciclo for) e acumulador (o nome adn onde vamos acumulando os resultados).
Suponhamos agora uma situação semelhante. Alguém anda perdido numa cidade, perfeitamente geométrica, e pede ajuda para se deslocar a um dado local da cidade. Recebe ajuda na forma de uma sequência de indicações do tipo Avança (A), Recua (R), Vira à Esquerda (E) ou Vira à Direita (D). Admitamos que o que se pretende é um programa que gere sequências válidas de indicações, de tamanho variável. O leitor não estranhará, depois de uma breve reflexão, que a solução proposta não lhe ofereça grandes dúvidas.
01.mport random
02.import random
03.def gera_comandos(tam):
04.    """
05.    Gera uma sequências de indicações de movimento numa cidade de tamanho tam.
06.    Padrão ciclo-acumulador
07.    """
08.    seq_comandos =''
09.    for i in range(tam):
10.        comando = random.choice('ARED')
11.        seq_comandos = seq_comandos + comando
12.    return seq_comandos
Olhando para estas soluções verificamos que o que as distingue é apenas os caracteres possíveis nos dois casos. Podemos então abstrair esse detalhe, e construir uma solução genérica que sirva para gerar qualquer sequência de caracteres, conhecido o alfabeto dos caracteres possíveis. Vamos a isso.
1.import random
2. 
3.def gera_comandos(tamanho, alfabeto):
4.    """ Gera uma sequência de comandos com elementos retirados aleatoriamente do alfabeto."""
5.    comandos = ''
6.    for i in range(tamanho):
7.        comandos = comandos + random.choice(alfabeto)
8.    return comandos
Mais uma vez verificamos que generalizar significa transformar uma constante (no caso a cadeia de ADN ou de indicações) num nome que aparece como parâmetro formal. Mas será que as versões concretas devem ser deitadas fora? Não necessariamente. Suponha que tem indicações sobre a probabilidade de ocorrência de um dos eventos. Como incorporar isso no programa. Vamos ver para o caso da indicação do percurso. Se a pessoa for competente então é provável que dê mais indicações de Avançar do que de Recuar e que privilegie também uma das indicações de Virar. Vamos ver como podemos incorporar essa indicação no código.
01.import random
02. 
03.def gera_comandos(n):
04.    """Gera n comandos aleatoriamente. Alguns movimentos são mais prováveis do que outros."""
05.    comandos = ''
06.    for i in range(n):
07.        if random.choice([0,0,0,1]) == 0:
08.            comandos += random.choice(['A','A', 'A','A','R'])
09.        else:
10.            comandos += random.choice(['E',’E’, 'D'])
11.    return comandos
Neste exemplo, avançar e recuar globalmente têm 75% de probabilidades de ocorrer, enquanto virar tem apenas 25%. Dentro de cada caso também há diferenças: avançar tem 80% de probabilidade de ocorrer e virar à esquerda 66%.

Sem comentários:

Enviar um comentário