pythonhangmanソルバー
次のような100行を含むcsvファイルを読み取るプログラムを作成しました。
1;S****L;SCHOOL
2;*A*G*A*;HANGMAN
次に、絞首刑執行人のゲームのように文字を推測してみてください。私の範囲は、すべての正しい文字と間違った文字を数え、それらを合計することです。コードは正常に機能します。1670年頃に正しい+間違った文字の推測を試みます。私のアプローチは、アルファベットからすべての文字を保存し、ファイルからすべての単語を読み取り、文字のすべての外観を合計して辞書に保存する辞書を作成することでした。好きなもの
{
"A" : 30,
"B" : 40
}
次に、すべての文字の出現に基づいてdictを並べ替え、最初に最も適切な文字を推測しようとします。
私の質問。試行回数を減らすために改善できることはありますか?
import csv
INPUT_FILE = "words.csv"
def oppenFile(): # function to read the file
with open(INPUT_FILE, "r", encoding="utf-8") as words:
reader = list(csv.reader(words, delimiter=";"))
return reader
def letterCount(): # function that count every the letter in the file and return a dict: {A : 2}
letters = dict.fromkeys("QWERTYUIOPĂÎASDFGHJKLȘȚÂZXCVBNM", 0)
words = oppenFile()
for w in range(len(words)):
for l in list(words[w][2]):
if l not in list(words[w][1]):
letters[l] += 1
return letters
def checkLetters(word, wholeWord, letters): # function that solve a word return the number of right + wrong attempts
attempts = 0
for letter, key in letters.items():
if letter in wholeWord and letter not in word:
attempts += 1
index = [i for i, lit in enumerate(wholeWord) if lit == letter]
letters[letter] -= len(index)
for j in range(len(index)):
word = word[:index[j]] + letter + word[(index[j] + 1):]
elif '*' not in word:
break
else:
attempts += 1
return attempts
def hangman():
words = oppenFile()
numberOfAttempts = 0
letters = letterCount()
for i in range(len(words)):
letters = dict(sorted(letters.items(), key=lambda x: x[1], reverse=True)) # sort the dict
numberOfAttempts += checkLetters(words[i][1], words[i][2], letters)
print(f"{numberOfAttempts} right + wrong attempts")
if __name__ == "__main__":
hangman()
回答
コードレビューへようこそ!
PEP-8
Pythonでは、クリーンで保守可能で一貫性のあるコードを作成するために、PEP-8スタイルガイドに従うのが一般的です(そして推奨されます)。
関数と変数はlower_snake_case、、クラスはUpperCamelCase、、定数はUPPER_SNAKE_CASE。で名前を付ける必要があります。
タイプヒント
新しいPythonバージョンでは、型ヒントを利用して、変数の型と関数パラメーターの概要を簡単に説明できます。
文字を数える
Pythonには、collections.Counter利用できる組み込みの機能が用意されています。
コメント
コメントはここではあまり役に立ちません。また、関数のコメントよりもdocstringを書くことをお勧めします。
変数名
ファイルを開き、そのポインタに。という名前を付けますwordsが、関数は単語のリストを返します。と呼ばれreader、これはwords?と呼ばれる変数に格納されます。
奇妙な変換
文字のそれぞれのカウントへのマッピングを辞書(ハッシュマップ/テーブル/ルックアップ)として生成し、それを2値タプルのリストに変換し、それを並べ替えて、辞書に戻します。どうして?dict持っている\$ O(1) \$ あなたの場合、ルックアップとソートは意味がありません。
インデックスを使用した反復
次のループ構造を使用します。
for i in range(len(words)):
ここでi、それ自体は目的を果たしていません。の使用法はすべてi、の形式words[i]です。wordsリスト自体の値を繰り返すことができます。
for word in words: