2
\$\begingroup\$

Hey guys I am trying to improve my Python Programming skills, I tried to build a hangman code. I know it is not perfect but I works. I am looking for some hints or advice to improve this script.

    txt_file = open('dictionnary.txt','r') # Open the file with read option

    words = txt_file.readlines() # Read all the lines 

    words =[word.replace('\n','') for word in words] # Remove '\n' and words is now a list

    import random

    random_number = random.randint(11,len(words)-1) # Choose a random number between 11 (to avoid words like 'aa', 'aaargh',etc) and the lenght of words

    word_to_guess = words[random_number]

    user_guesses=['#' for i in word_to_guess]




# Function to check if the input letter is in the world to guess if yes replace '#' with the input letter 

def check_index_and_replace(letter):
    letter_index=[i[0] for i in enumerate(word_to_guess) if i[1]==letter]
    for i in letter_index:
        user_guesses[i] = user_guesses[i].replace('#',letter)
    return(user_guesses)

# Function to tell how many letter to guess left 

def letterleft(user_guesses):
    return(user_guesses.count('#'))


# My core code (input and prints)

tries = int(input('How many tries you want ? '))
test = 0    
while test < tries+1:
    letter = input('Try a letter ')
    print(check_index_and_replace(letter))
    print(letterleft(user_guesses),'letter left to guess !')
    test=test+1
print(word_to_guess)
\$\endgroup\$
1
  • 3
    \$\begingroup\$ The current question title, which states your concerns about the code, applies to too many questions on this site to be useful. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly. \$\endgroup\$
    – Mast
    May 27, 2020 at 19:31

1 Answer 1

1
\$\begingroup\$

Getting lines from a file

You can use simple list comprehension to get all the lines from a file.

words = [word for word in open("dictionary.txt", "r")]

However, this does not ensure the file will be closed. To be safe, I would do this:

with open("dictionary.txt", "r") as file:
    words = [word for word in file]

The with ensures the file will be closed once you're done working with the file.

Globals

With a small program like this, globals can be quite helpful since you don't have to pass word_to_guess through functions. However, as you begin to develop more complicated programs, you should be mindful and careful about your globals "leaking" into other parts of your programs, should you be using multiple files.

Random choices

Instead of generating a random number between the min and max of the list, use random.choice(...) to chose a random word from the dictionary. And if you're worried about the beginning of the alphabet, you can create a buffer variable and splice the list so the beginning of the alphabet is removed.

# The first 11 words will be removed from the list #
buffer = 11
word_to_guess = random.choice(words[buffer:])

check_index_and_replace

Instead of casting replace on each index, you can use an if statement to make sure the letter is equal to the letter in word_to_guess, and in the same position. If it is, then assign that letter to the position in the list.

from typing import List

def check_and_replace(letter: str) -> List[str]:
    """
    For each character in the word, if that character
    is equal to the passed letter, then the position in
    user_guesses is changed to that letter.
    """
    for idx, char in enumerate(word_to_guess):
        if char == letter:
            user_guesses[idx] = letter
    return user_guesses

Type Hints

These help yourself and other people looking at your code understand what types of variables are being passed and returned to/from functions. As above, the function accepts a str for letter, and returns a list of strings.

lettersleft

If you have a function that only has one line, most of the time you can delete the function and put that line where the function is called. And since this function utilizes a built-in function to count the occurrences of # in the list, this function doesn't need to be written.

The main body

Instead of keeping track for each try, use a for loop and only run as many times as the user inputed. If the user enters 4, the loop only runs four times.

When I first played this game, it was impossible to win. I could guess the word, but the game wouldn't end. A quick fix is to check if the number of letters left is 0. If it is, display a game won message and exit the program. If it isn't, print how many are left and go through the loop again.


All in all, your program would look something like this:

import random
from typing import List

with open("dictionary.txt", "r") as file:
    words = [word for word in file]
buffer = 11
word_to_guess = random.choice(words[buffer:])
user_guesses = ['#' for _ in word_to_guess]

def check_and_replace(letter: str) -> List[str]:
    """
    For each character in the word, if that character
    is equal to the passed letter, then the position in
    user_guesses is changed to that letter.
    """
    for idx, char in enumerate(word_to_guess):
        if char == letter:
            user_guesses[idx] = letter
    return user_guesses

def main():
    tries = int(input('How many tries you want? '))
    for _ in range(tries):
        letter = input('Try a letter ')
        print(check_and_replace(letter))
        letters_left = user_guesses.count("#")
        if letters_left == 0:
            print("You guessed the word!")
            quit()
        else:
            print(letters_left, "letters remaining!")
    print("The word was", word_to_guess)

if __name__ == '__main__':
    main()
\$\endgroup\$
2
  • \$\begingroup\$ Wow Thank you very much for you reply it helps a lot. However I do not understand why you suggest to close my file 'dictionary.txt'. I read that indeed a file open must be close "manually" but I don't understand why I need to close it since I store its content in a list right after I open it. Again thank you very much for your suggestion ! \$\endgroup\$
    – Ismouss
    Jun 4, 2020 at 18:06
  • 1
    \$\begingroup\$ @Ismouss Take a look at this. A great answer about why you should close files. \$\endgroup\$
    – Linny
    Jun 5, 2020 at 0:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.