segunda-feira, 18 de novembro de 2013

Amigos, Amigos,...

Um dos problemas do livro (problema 5.8) fala-nos de palavras amigas. Elas são amigas se o número de posições em que os respectivos caracteres difere for inferior a 10%. A propósito deste problema um aluno de IPRP enviou-me o seguinte email (de que reproduzo a parte substantiva).

“Para comparar caractere a caractere estou a utilizar um ciclo for: ....... for car in cad1:         if cad1[car] != cad2[car] ........ ou seja vou comparar os carateres de cada cadeia na mesma posição e ver se eles são diferentes o python diz-me que o que esta dentro de cad1 e cad2 tem de ser um numero inteiro tendo o meu código dado erro.”

Qual é o problema? A resposta remete para os dois modos de percorrer um ciclo for: por posição ou por conteúdo. No caso do aluno ele está a fazer uma travessia do ciclo por conteúdo:
1.for car in cad1:
Depois no teste usa a operação de indexação, que permite aceder ao conteúdo mas por posição! Por isso o erro de dizer que o índice tem que ser um inteiro. A solução passa por fazer a travessia por posição:
1.for i in range(len(cad1)):
2.   if cad1[i] != cad2[i]
Já agora o programa completo.
01.def amigas(cad_1, cad_2):
02.    """palavras que diferem em menos de 10% dizem-se amigas. Assume igual comprimento"""
03.    # Calcula distancia
04.    diferem = 0
05.    for i in range(len(cad_1)):
06.        if cad_1[i] != cad_2[i]:
07.            diferem += 1
08.    percentagem = diferem / len(cad_1)
09.    return percentagem < 0.1
Este programa funciona para qualquer tipo de sequências: cadeias de caracteres, tuplos e listas. O curioso da questão é que a versão do aluno podia correr sem dar erro caso se use um tuplo (ou uma lista) formado(a) por inteiros que correspondam a índices válidos dessas sequências! Se não acredita experimente:
01.def amigas(cad_1, cad_2):
02.    """palavras que diferem em menos de 10% dizem-se amigas. Assume igual comprimento"""
03.    # Calcula distancia
04.    diferem = 0
05.    for car in cad_1:
06.        if cad_1[car] != cad_2[car]:
07.            diferem += 1
08.    percentagem = diferem / len(cad_1)
09.    return percentagem < 0.1
10. 
11.if __name__ == '__main__':
12.    c1 = [0,1,2,3,4,5,6,7,8,9,0,1,3,3,4,5,6,7,8,9,0]
13.    c2 = [0,1,4,3,4,5,6,7,8,9,0,1,3,3,4,5,6,7,8,9,0]
14.    c3 = (0,1,2,3,4)
15.    c4 = (4,3,2,1,0)
16.    print(amigas(c1,c2))
17.    print(amigas(c3,c4))
Moral desta última parte da história: muitas vezes os programas funcionam para certos valores dos parâmetros reais e parece que está tudo bem... quando não está.

Sem comentários:

Enviar um comentário