python hangman solver

Oct 08 2020

Saya menulis program yang membaca file csv yang berisi 100 baris yang terlihat seperti:

1;S****L;SCHOOL
2;*A*G*A*;HANGMAN

lalu coba tebak huruf-huruf seperti dalam permainan algojo. Ruang lingkup saya adalah menghitung setiap huruf yang benar dan salah dan kemudian menjumlahkannya. Kode berfungsi dengan baik, saya mendapatkan sekitar 1670 upaya benar + salah untuk menebak huruf. Pendekatan saya adalah membuat kamus tempat saya menyimpan semua huruf dari alfabet dan membaca setiap kata dari file lalu menjumlahkan setiap kemunculan huruf dan menyimpannya dalam kamus. Sesuatu seperti

{
   "A" : 30,
   "B" : 40
}

Kemudian saya mengurutkan dikt berdasarkan setiap kemunculan huruf dan pertama-tama mencoba menebak huruf dengan tampilan terbanyak.

Pertanyaan saya. Apakah ada sesuatu yang bisa saya tingkatkan untuk mendapatkan jumlah percobaan yang lebih sedikit?

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()

Jawaban

5 hjpotter92 Oct 08 2020 at 04:07

Selamat datang di Review Kode!

PEP-8

Dalam python, adalah umum (dan disarankan) untuk mengikuti panduan gaya PEP-8 untuk menulis kode yang bersih, dapat dipelihara dan konsisten.

Fungsi dan variabel harus diberi nama dalam a lower_snake_case, kelas sebagai UpperCamelCase, dan konstanta sebagai UPPER_SNAKE_CASE.

Ketik petunjuk

Dengan versi python yang lebih baru, Anda dapat menggunakan petunjuk tipe untuk memberikan gambaran singkat tentang tipe variabel dan parameter fungsi.

Menghitung huruf

Python menyediakan inbuilt collections.Counteruntuk Anda manfaatkan.

Komentar

Komentar tidak terlalu membantu di sini. Juga, lebih suka menulis docstring daripada komentar untuk fungsi.

Nama variabel

Anda membuka file, dan menamai penunjuknya sebagai words, sedangkan fungsi mengembalikan daftar kata; disebut reader, yang pada gilirannya disimpan dalam variabel yang disebut words?

Pertobatan yang aneh

Anda membuat pemetaan huruf ke jumlah masing-masing, sebagai kamus (hash-map / table / lookup), lalu mengonversinya menjadi daftar tupel bernilai 2, mengurutkan, dan mengubahnya kembali ke kamus. Mengapa? dictmemiliki \$ O(1) \$ pencarian dan penyortiran tidak masuk akal dalam kasus Anda.

Iterasi dengan indeks

Anda menggunakan struktur loop berikut:

for i in range(len(words)):

di mana, idengan sendirinya tidak ada gunanya. Setiap kejadian penggunaan iadalah dalam bentuk words[i]. Anda bisa mengulang nilai wordslist itu sendiri:

for word in words: