Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Função que determina se todas as letras contidas em uma string estão na outra

def isWordGuessed(secretWord, lettersGuessed):
    '''
    secretWord: string, the word the user is guessing
    lettersGuessed: list, what letters have been guessed so far
    returns: boolean, True if all the letters of secretWord are in lettersGuessed;
      False otherwise
    '''
    certas =0
    for i in range(len(secretWord)):
        if secretWord[i] in lettersGuessed:
            certas += 1

    #print(certas)

    if certas == len(secretWord):
        return True


    else:
        return False

secretWord = 'durian' 
#lettersGuessed = ['e', 'i', 'k', 'p', 'r', 's']
#lettersGuessed = ['e', 'a', 'l', 'p', 'e']
#isWordGuessed('durian', ['h', 'a', 'c', 'd', 'i', 'm', 'n', 'r', 't', 'u'])
lettersGuessed = ['h', 'a', 'c', 'd', 'i', 'm', 'n', 'r', 't', 'u']
print(isWordGuessed(secretWord, lettersGuessed))

Objetivo é determinar se todas as letras de secretWord estão contidas em lettersGuessed.

O meu código está funcionando. Existe alguma maneira Pythonica de fazer?

1 resposta
solução!

Oi, Edson! Então, na verdade, temos sim algumas maneiras de deixar esse código mais pythônico. Lembrando que pythônico, em geral, significa mais simples, elegante, legível (vide >>> import this). Além dessas palavras chaves, temos documentos, como o PEP 8, que nos indicam padrões de estilo que nosso código Python idealmente deve seguir.

Analisando seu código, conseguimos ver alguns pontos desnecessários na implementação de sua função, que, se olharmos duas vezes, talvez não valha a pena manter. Um exemplo é no seu loop for:

for i in range(len(secretWord)):
        if secretWord[i] in lettersGuessed:
            certas += 1

Repare que queremos iterar por todas as letras da variável secretWord, mas estamos iterando por todos os números de 0 até o comprimento da variável. Esse range(len()) não nos traz nenhuma vantagem, então podemos substituir todo esse bloco por:

for letter in secretWord:
        if letter in lettersGuessed:
            certas += 1

Outro exemplo simples é no caso do retorno:

if certas == len(secretWord):
        return True
else:
        return False

Quando usamos o return, a função automaticamente se encerra. Assim, é padrão na programação em geral deixar esse return False (claro que nem sempre precisa ser False) fora de um else, simplificando um pouco as coisas, olha:

if certas == len(secretWord):
        return True
return False

Agora, além desses dois pontos, acho que podemos simplificar ainda um pouco a própria lógica da função. Veja, será que precisamos mesmo da variável certas? Poderíamos, em vez de contar quantas letras batem, apenas retornar logo False caso alguma letra não bata, dessa forma:

def isWordGuessed(secretWord, lettersGuessed):
    for letter in secretWord:
        if letter not in lettersGuessed:
            return False
    return True

Agora conseguimos minimizar e ainda deixar nosso código até um pouco mais claro, não acha? Outra coisa que podemos fazer, para evitar loops desnecessários em strings como 'aaaaaaaaaaaaaaaaaaaaaaaa', é transformar nossa string em um objeto set, com a função construtora set(), que é uma estrutura que armazena valores sem repetição (ou set('aaaaaaaaaaaaaaaaaaaaaaaa') retorna {'a'}):

def isWordGuessed(secretWord, lettersGuessed):
    for letter in set(secretWord):
        if letter not in lettersGuessed:
            return False
    return True

Acho que isso pode deixar ainda mais legal sua função, Edson! O que você acha?

PS: só porque você usou o termo pythônico, vou dar outra dica que o PEP 8 fala sobre: nomes de variáveis. No Python, geralmente usamos o padrão snake case para nomear variáveis, funções e métodos, assim:

is_word_guessed(secret_word, letters_guessed)

E deixamos EssePadraoDeMaiusculas para nomes de classe. Claro, isso não vai fazer diferença de fato no código, mas achei que você poderia achar interessante :)! Abraços e bons estudos, Edson! (E obrigado pelas contribuições no fórum!)