Python Hangman Solver

Oct 08 2020

Ich habe ein Programm geschrieben, das eine CSV-Datei liest, die 100 Zeilen enthält, die wie folgt aussehen:

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

Versuchen Sie dann, die Buchstaben wie in einem Henker-Spiel zu erraten. Mein Ziel ist es, alle richtigen und falschen Buchstaben zu zählen und sie dann zusammenzufassen. Der Code funktioniert gut, ich bekomme um 1670 richtige + falsche Versuche, die Buchstaben zu erraten. Mein Ansatz war es, ein Wörterbuch zu erstellen, in dem ich alle Buchstaben des Alphabets speichere und alle Wörter aus der Datei lese, dann jedes Erscheinungsbild eines Buchstabens summiere und sie im Wörterbuch speichere. Etwas wie

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

Dann sortiere ich das Diktat nach jedem Buchstabenvorkommen und versuche zuerst, den Buchstaben mit dem meisten Apparat zu erraten.

Meine Frage. Kann ich etwas verbessern, um weniger Versuche zu bekommen?

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

Antworten

5 hjpotter92 Oct 08 2020 at 04:07

Willkommen bei Code Review!

PEP-8

In Python ist es üblich (und empfohlen), den PEP-8-Styleguide zu befolgen, um sauberen, wartbaren und konsistenten Code zu schreiben.

Funktionen und Variablen sollten in a lower_snake_case, Klassen als UpperCamelCaseund Konstanten als benannt werden UPPER_SNAKE_CASE.

Geben Sie einen Hinweis ein

Bei neueren Python-Versionen können Sie Typhinweise verwenden, um einen kurzen Überblick über den Typ der Variablen und Funktionsparameter zu erhalten.

Buchstaben zählen

Python bietet eine integrierte Funktion, die collections.CounterSie verwenden können.

Bemerkungen

Die Kommentare helfen hier nicht wirklich. Schreiben Sie außerdem lieber Dokumentstrings als Kommentare für Funktionen.

Variablennamen

Sie öffnen eine Datei und benennen ihren Zeiger als words, während die Funktion eine Liste von Wörtern zurückgibt. aufgerufen reader, was wiederum in einer Variablen namens gespeichert ist words?

Seltsame Umbauten

Sie generieren eine Zuordnung von Buchstaben zu ihren jeweiligen Zählwerten als Wörterbuch (Hash-Map / Tabelle / Lookup), konvertieren sie dann in eine Liste mit zwei Tupeln, sortieren diese und konvertieren sie zurück in ein Wörterbuch. Warum? dicthat \$ O(1) \$ Nachschlagen und Sortieren macht in Ihrem Fall keinen Sinn.

Iteration mit Index

Sie verwenden die folgende Schleifenstruktur:

for i in range(len(words)):

wo ian sich keinen Zweck erfüllt. Jedes Auftreten der Nutzung von ihat die Form words[i]. Sie können einfach die Werte der wordsListe selbst durchlaufen :

for word in words: