1

秘密の単語のロックを解除するために、ユーザーが文字を推測する必要があるプログラムを作成しようとしています。最大 8 回の推測の前に秘密の単語が正しく推測された場合、関数は true を返します。それ以外の場合、関数は false を返します。何らかの理由で、私の関数は正しい出力を生成しません。文字「a」を入力すると、「これまでに推測された文字: ['a']」と出力され、プログラムが終了します。この問題を解決するには助けが必要です。

secretWord = 'hello'
lettersGuessed = []


def isWordGuessed(secretWord,lettersGuessed):
  guess  = 0
  while guess <= 8:
    secretLetters = list(secretWord)
    secretWordLen = len(secretLetters)
    letter = input('Enter a letter: ')
    lettersGuessed.append(letter)

    print('Letters guessed so far: ',lettersGuessed)

    if letter not in secretLetters:
        guess += 1

    while letter in secretLetters:
        secretLetters.remove(letter)

    if secretLetters == []:
       return True
    else:
       return False



   isWordGuessed(secretWord,lettersGuessed)
4

3 に答える 3

2

最初の問題は、kwatford が説明したように、毎回ループを返すことです。ifステートメントをwhileループの外に移動することで修正できます。

次の問題は、Vorticity が説明したように、ユーザーが単語全体を推測したとしても、決して早く返されないことです。これを修正するには、ifパーツをループ内に戻しますが、elseパーツをループ外に残します (つまり、 は不要になりますelse) 。

その後、ループを毎回実行しているため、まだ機能しません。したがって、1 回の推測ですべての文字を推測した場合にのみ勝つことができます (単語が、言う、またはでない限り、これは不可能です)。これを修正するには、その行をループの外に移動します。secretLetters = list(secretWord)"a""aaaaa"

すべてを一緒に入れて:

def isWordGuessed(secretWord,lettersGuessed):
  guess  = 0
  secretLetters = list(secretWord)
  while guess <= 8:
    secretWordLen = len(secretLetters)
    letter = input('Enter a letter: ')
    lettersGuessed.append(letter)

    print('Letters guessed so far: ',lettersGuessed)

    if letter not in secretLetters:
        guess += 1

    while letter in secretLetters:
        secretLetters.remove(letter)

    if secretLetters == []:
       return True

  return False

補足として、これを単純化するためにできることはたくさんあります。

まず、秘密の単語に含まれるすべての文字のセットが本当に必要なだけです。順序や、それぞれの文字のコピー数などを知る必要はありません。したがって、 の代わりに をlist使用しsetます。これは、ループアラウンドが必要ないことも意味しますsecretLetters.remove(letter)

もっと自明なことに、あなたはそれを作成しますsecretWordLenが、決して使用しません。

また、呼び出し元から渡された a を受け入れて追加しますlettersGuessedが、呼び出し元は空のリストを渡すだけで、事後にそれを使用することはありません。また、呼び出し元の利益のためにそれを変更する必要がない場合は、文字列として保持するだけでよいため、ユーザーはhelpの代わりに表示されます['h', 'e', 'l', 'p']。これははるかに優れています。

また、真実ではない可能性がある場合でもテストされているケースがいくつかあります。

最後に、空のリスト (またはセット、またはその他のシーケンス) は false であるため、空のリストと明示的に比較する理由はありません。

その間、インデントを見やすくするために間隔を PEP8 化します。

そう:

def isWordGuessed(secretWord):
    guess = 0
    lettersGuessed = ''
    secretLetters = set(secretWord)
    while guess <= 8:
        letter = input('Enter a letter: ')
        lettersGuessed += letter
        print('Letters guessed so far:', lettersGuessed)
        if letter not in secretLetters:
            guess += 1
        else:
            secretLetters.remove(letter)
            if not secretLetters:
                return True
    return False
于 2013-03-28T00:55:45.567 に答える
2

最後のifステートメントがインデントされすぎているため、whileループの一部になっています。条件の両方の分岐によって関数が戻るため、常にループの最初の繰り返しで戻ります。

于 2013-03-28T00:48:30.747 に答える
0

Falseケースの返品を移動するだけです。基本的に、現在のコードの書き方では、ループの最初に戻ることはありません。また、abarnert が指摘したように、ループするたびに secretLetters を再初期化しているため、ループを終了することはありません。ループの外で初期化する必要があります。コードは次のようになります。

secretWord = 'hello'
lettersGuessed = []

def isWordGuessed(secretWord,lettersGuessed):
    guess  = 0
    secretLetters = list(secretWord)
    secretWordLen = len(secretLetters)
    while guess <= 8:
        letter = input('Enter a letter: ')
        lettersGuessed.append(letter)

        print('Letters guessed so far: ',lettersGuessed)

        if letter not in secretLetters:
            guess += 1

        while letter in secretLetters:
            secretLetters.remove(letter)

        if secretLetters == []:
            #Return true if all correct letters have been guessed
            return True

    #Return false if guessed incorrectly eight times
    return False
于 2013-03-28T00:50:45.693 に答える