solveur python python
J'ai écrit un programme qui lit un fichier csv contenant 100 lignes qui ressemblent à:
1;S****L;SCHOOL
2;*A*G*A*;HANGMAN
puis essayez de deviner les lettres comme dans un jeu du pendu. Mon objectif est de compter toutes les bonnes et mauvaises lettres, puis de les résumer. Le code fonctionne bien, j'obtiens environ 1670 bonnes + mauvaises tentatives pour deviner les lettres. Mon approche était de créer un dictionnaire dans lequel je stockais toutes les lettres de l'alphabet et lisais tous les mots du fichier, puis additionnais toutes les apparences d'une lettre et les stockais dans le dictionnaire. Quelque chose comme
{
"A" : 30,
"B" : 40
}
Ensuite, je trie le dict en fonction de chaque occurrence de lettre et j'essaie d'abord de deviner la lettre avec le plus d'apparence.
Ma question. Est-ce que je peux améliorer quelque chose pour obtenir un plus petit nombre de tentatives?
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()
Réponses
Bienvenue dans Code Review!
PEP-8
En python, il est courant (et recommandé) de suivre le guide de style PEP-8 pour écrire du code propre, maintenable et cohérent.
Les fonctions et les variables doivent être nommées dans a lower_snake_case, classes as UpperCamelCaseet constantes as UPPER_SNAKE_CASE.
Indication de type
Avec les nouvelles versions de python, vous pouvez utiliser l'indication de type pour donner un bref aperçu du type de variables et de paramètres de fonction.
Compter les lettres
Python fournit un outil intégré collections.Counterque vous pouvez utiliser.
commentaires
Les commentaires n'aident pas vraiment ici. Préférez également l'écriture de docstring plutôt que les commentaires pour les fonctions.
Noms de variables
Vous ouvrez un fichier et nommez son pointeur comme words, tandis que la fonction renvoie une liste de mots; appelé reader, qui à son tour est stocké dans une variable appelée words?
Conversions étranges
Vous générez un mappage des lettres avec leurs nombres respectifs, sous forme de dictionnaire (hash-map / table / lookup), puis convertissez-le en liste de tuple à 2 valeurs, triez-le et reconvertissez-le en dictionnaire. Pourquoi? dicta \$ O(1) \$ la recherche et le tri n'ont aucun sens dans votre cas.
Itération avec index
Vous utilisez la structure de boucle suivante:
for i in range(len(words)):
où, ien soi, ne sert à rien. Chaque occurrence d'utilisation de iest de la forme words[i]. Vous pouvez simplement parcourir les valeurs de la wordsliste elle-même:
for word in words: