python cellat çözücü

Oct 08 2020

Aşağıdaki gibi görünen 100 satır içeren bir csv dosyasını okuyan bir program yazdım:

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

sonra bir cellat oyununda olduğu gibi harfleri tahmin etmeye çalışın. Benim amacım her doğru ve yanlış harfleri saymak ve sonra bunları özetlemek. Kod iyi çalışıyor, harfleri tahmin etmek için yaklaşık 1670 doğru + yanlış girişimler alıyorum. Yaklaşımım, alfabedeki tüm harfleri sakladığım ve dosyadaki her kelimeyi okuduğum ve ardından bir harfin her görünümünü toplayıp sözlükte sakladığım bir sözlük oluşturmaktı. Gibi bir şey

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

Sonra dikteyi her harf oluşumuna göre sıralıyorum ve önce en belirgin olan harfi tahmin etmeye çalışıyorum.

Benim sorum. Daha az sayıda deneme yapabilmek için geliştirebileceğim bir şey mi?

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

Yanıtlar

5 hjpotter92 Oct 08 2020 at 04:07

Kod İncelemesine Hoş Geldiniz!

BEP-8

Python'da temiz, sürdürülebilir ve tutarlı kod yazmak için PEP-8 stil kılavuzunu takip etmek yaygındır (ve önerilir).

Fonksiyonlar ve değişkenler a lower_snake_case, sınıflar as UpperCamelCaseve sabitler olarak adlandırılmalıdır UPPER_SNAKE_CASE.

Tip ipucu

Daha yeni python sürümleriyle, değişkenlerin ve işlev parametrelerinin türlerine kısa bir genel bakış sağlamak için tür ipuçlarından yararlanabilirsiniz.

Harfleri saymak

Python, yararlanmanız için bir dahili sağlar collections.Counter.

Yorumlar

Yorumlar burada gerçekten yardımcı olmuyor. Ayrıca, işlevler için açıklamalar yerine docstring yazmayı tercih edin.

Değişken isimler

Bir dosyayı açarsınız ve işaretçisini olarak adlandırırsınız words, oysa işlev bir sözcük listesi döndürür; denir reader, hangisi sırayla adlı bir değişkende saklanır words?

Garip dönüşümler

Bir sözlük olarak (hash-map / table / lookup) ilgili sayılarına harflerin bir eşlemesini oluşturursunuz, sonra onu 2-değerli demet listesine dönüştürür, sıralar ve tekrar sözlüğe çevirirsiniz. Neden? dictvar \$ O(1) \$ Arama ve sıralama sizin durumunuzda bir anlam ifade etmiyor.

Dizin ile yineleme

Aşağıdaki döngü yapısını kullanırsınız:

for i in range(len(words)):

nerede, ikendi içinde hiçbir amaca hizmet edilmektedir. Her kullanım işekli biçimindedir words[i]. wordsListenin kendisinin değerlerini yineleyebilirsiniz :

for word in words: