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.
import random
def gera_adn(tam):
"""Gera uma cadeia de ADN de tamanho tam. Padrão ciclo-acumulador"""
adn =''
for i in range(tam):
base = random.choice('TACG')
adn = adn + base
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.
mport random
import random
def gera_comandos(tam):
"""
Gera uma sequências de indicações de movimento numa cidade de tamanho tam.
Padrão ciclo-acumulador
"""
seq_comandos =''
for i in range(tam):
comando = random.choice('ARED')
seq_comandos = seq_comandos + comando
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.
import random
def gera_comandos(tamanho, alfabeto):
""" Gera uma sequência de comandos com elementos retirados aleatoriamente do alfabeto."""
comandos = ''
for i in range(tamanho):
comandos = comandos + random.choice(alfabeto)
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.
import random
def gera_comandos(n):
"""Gera n comandos aleatoriamente. Alguns movimentos são mais prováveis do que outros."""
comandos = ''
for i in range(n):
if random.choice([0,0,0,1]) == 0:
comandos += random.choice(['A','A', 'A','A','R'])
else:
comandos += random.choice(['E',’E’, 'D'])
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