This is my hangman game code for my GCSE computer science coursework. It has been submitted but I was wondering if there is anyway to improve it.

```
import random
import time

#Variables holding different words for each difficulty
EASYWORDS = open("Easy.txt","r+")
words = []
for item in EASYWORDS:
    words.append(item.strip('\n'))
MEDWORDS = open("Med.txt","r+")
words = []
for item in MEDWORDS:
    words.append(item.strip('\n'))

HARDWORDS = open("Hard.txt","r+")
words = []
for item in HARDWORDS:
    words.append(item.strip('\n'))

INSANEWORDS = open("Insane.txt", "r+")
words = []
for item in INSANEWORDS:
    words.append(item.strip('\n'))
#Where the user picks a difficulty
def difficulty():

    print("easy\n")
    print("medium\n")
    print("hard\n")
    print("insane\n")

    menu=input("Welcome to Hangman, type in what difficulty you would like... ").lower()

    if menu == "hard" or menu == "h":

        hard()

    elif menu == "medium" or menu == "m" or menu =="med":

        med()

    elif menu == "easy" or menu == "e":

        easy()

    elif menu == "insane" or menu == "i":

        insane()

    else:   
        print("Please type in either hard, medium, easy or insane!")
        difficulty()

def difficulty2():

    print("Easy\n")
    print("Medium\n")
    print("Hard\n")
    print("Insane\n")
    print("Quit\n")

    menu=input("Welcome to Hangman, type in what difficulty you would like. Or would you like to quit the game?").lower()

    if menu == "hard" or menu == "h":

        hard()

    elif menu == "medium" or menu == "m" or menu =="med":

        med()

    elif menu == "easy" or menu == "e":

        easy()

    elif menu == "insane" or menu == "i":

        insane()

    elif menu == "quit" or "q":
        quit()

    else:   
        print("Please type in either hard, medium, easy or insane!")
        difficulty()

#if the user picked easy for their difficulty
def easy():
    global score 
    print ("\nStart guessing...")

    time.sleep(0.5)

    word = random.choice(words).lower()
    guesses = ''
    fails = 0
    while fails >= 0 and fails < 10:         
        failed = 0                
        for char in word:      
            if char in guesses:    
                print (char,)

            else:
                print ("_"),     
                failed += 1    
        if failed == 0:        
            print ("\nYou won, WELL DONE!")
            score = score + 1
            print ("your score is,", score)
            print ("the word was, ", word)
            difficultyEASY()

        guess = input("\nGuess a letter:").lower()
        while len(guess)==0:
            guess = input("\nTry again you muppet:").lower()
        guess = guess[0]
        guesses += guess 
        if guess not in word:
            fails += 1
            print ("\nWrong")

            if fails == 1:
                print ("You have", + fails, "fail....WATCH OUT!" )
            elif fails >= 2 and fails < 10:
                print ("You have", + fails, "fails....WATCH OUT!" )
            if fails == 10:
                print ("You Lose\n")
                print ("your score is, ", score)
                print ("the word was,", word)
                score = 0
                difficultyEASY()

#if the user picked medium for their difficulty
def med():
    global score 
    print ("\nStart guessing...")

    time.sleep(0.5)

    word = random.choice(words).lower()
    guesses = ''
    fails = 0
    while fails >= 0 and fails < 10:           
        failed = 0                
        for char in word:      
            if char in guesses:    
                print (char,)    

            else:
                print ("_"),     
                failed += 1    
        if failed == 0:        
            print ("\nYou won, WELL DONE!")
            score = score + 1
            print ("your score is,", score)
            difficultyMED()

        guess = input("\nGuess a letter:").lower()
        while len(guess)==0:
            guess = input("\nTry again you muppet:").lower()
        guess = guess[0]
        guesses += guess   
        if guess not in word:  
            fails += 1        
            print ("\nWrong")

            if fails == 1:
                print ("You have", + fails, "fail....WATCH OUT!" )
            elif fails >= 2 and fails < 10:
                print ("You have", + fails, "fails....WATCH OUT!" ) 
            if fails == 10:           
                print ("You Lose\n")
                print ("your score is, ", score)
                print ("the word was,", word)
                score = 0 
                difficultyMED()     

#if the user picked hard for their difficulty
def hard():
    global score  
    print ("\nStart guessing...")

    time.sleep(0.5)

    word = random.choice(words).lower()
    guesses = ''
    fails = 0
    while fails >= 0 and fails < 10:  #try to fix this         
        failed = 0                
        for char in word:      
            if char in guesses:    
                print (char,)    

            else:
                print ("_"),     
                failed += 1    
        if failed == 0:        
            print ("\nYou won, WELL DONE!")
            score = score + 1
            print ("your score is,", score)
            difficultyHARD()

        guess = input("\nGuess a letter:").lower()
        while len(guess)==0:
            guess = input("\nTry again you muppet:").lower()
        guess = guess[0]
        guesses += guess   
        if guess not in word:  
            fails += 1        
            print ("\nWrong")

            if fails == 1:
                print ("You have", + fails, "fail....WATCH OUT!" )
            elif fails >= 2 and fails < 10:
                print ("You have", + fails, "fails....WATCH OUT!" ) 
            if fails == 10:           
                print ("You Lose\n")
                print ("your score is, ", score)
                print ("the word was,", word)
                score = 0 
                difficultyHARD()

#if the user picked insane for their difficulty
def insane():
    global score  
    print ("This words may contain an apostrophe. \nStart guessing...")

    time.sleep(0.5)

    word = random.choice(words).lower()
    guesses = ''
    fails = 0
    while fails >= 0 and fails < 10:  #try to fix this         
        failed = 0                
        for char in word:      
            if char in guesses:    
                print (char,)    

            else:
                print ("_"),     
                failed += 1    
        if failed == 0:        
            print ("\nYou won, WELL DONE!")
            score = score + 1
            print ("your score is,", score)
            difficultyINSANE()

        guess = input("\nGuess a letter:").lower()
        while len(guess)==0:
            guess = input("\nTry again you muppet:").lower()
        guess = guess[0]
        guesses += guess   
        if guess not in word:  
            fails += 1        
            print ("\nWrong")

            if fails == 1:
                print ("You have", + fails, "fail....WATCH OUT!" )
            elif fails >= 2 and fails < 10:
                print ("You have", + fails, "fails....WATCH OUT!" ) 
            if fails == 10:           
                print ("You Lose\n")
                print ("your score is, ", score)
                print ("the word was,", word)
                score = 0 
                difficultyINSANE()

def start():

    Continue = input("Do you want to play hangman?").lower()
    while Continue in ["y", "ye", "yes", "yeah"]:
        name = input("What is your name? ")
        print ("Hello, " + name, "Time to play hangman! You have ten guesses to win!")
        print ("\n")
        time.sleep(1)
        difficulty()
    else:
        quit

#whether they want to try a diffirent difficulty or stay on easy

def difficultyEASY():
    diff = input("Do you want to change the difficulty?. Or quit the game? ")
    if diff == "yes" or difficulty =="y":
        difficulty2()
    elif diff == "no" or diff =="n":
        easy()

#whether they want to try a diffirent difficulty or stay on medium

def difficultyMED():
    diff = input("Do you want to change the difficulty?. Or quit the game? ")
    if diff == "yes" or difficulty =="y":
        difficulty2()
    elif diff == "no" or diff =="n":
        med()

#whether they want to try a diffirent difficulty or stay on hard

def difficultyHARD():
    diff = input("Do you want to change the difficulty?. Or quit the game? ")
    if diff == "yes" or difficulty =="y":
        difficulty2()
    elif diff == "no" or diff =="n":
        hard()

#whether they want to try a diffirent difficulty or stay on insane

def difficultyINSANE():
    diff = input("Do you want to change the difficulty?. Or quit the game? ")
    if diff == "yes" or difficulty =="y":
        difficulty2()
    elif diff == "no" or diff =="n":
        insane()

score = 0

start()

```
['https://codereview.stackexchange.com/questions/118996', 'https://codereview.stackexchange.com', 'https://codereview.stackexchange.com/users/96787/']
Input checking
==============

The way you're currently checking input is clunky, hard to write, and hard to read. For example, you have the following chunk of code:

> 
> 
> ```
> menu=input("Welcome to Hangman, type in what difficulty you would like... ").lower()
> 
> if menu == "hard" or menu == "h":
> 
>     hard()
> 
> elif menu == "medium" or menu == "m" or menu =="med":
> 
>     med()
> 
> elif menu == "easy" or menu == "e":
> 
>     easy()
> 
> elif menu == "insane" or menu == "i":
> 
>     insane()
> 
> else:   
>     print("Please type in either hard, medium, easy or insane!")
>     difficulty()
> 
> ```
> 
> 

There are quite a few things that can be improved here, so let's start with the obvious. Rather than having multiple individual conditional expressions to check the value of a variable, simply create a list of all possible values and use the `in` operator to check the variable's value, like this, for example:

```
if menu in ["medium", "med", "m"]:
    med()

```

Next, I'd suggest that you add a `.strip()` call to the following line:

> 
> 
> ```
> menu=input("Welcome to Hangman, type in what difficulty you would like... ").lower()
> 
> ```
> 
> 

The [`.strip()`](https://docs.python.org/3/library/string.html#string.strip) function, when no arguments are specified, will remove leading and trailing whitespace. This means that a user can enter something like `" med "` without worrying that the program might reject their input. In addition, you could also consider using [`re.sub`](https://docs.python.org/3/library/re.html#re.sub7) if you want to get rid of additional characters.

---

Building word lists
===================

You've got a lot of repetition in the following chunk of code:

> 
> 
> ```
> #Variables holding different words for each difficulty
> EASYWORDS = open("Easy.txt","r+")
> words = []
> for item in EASYWORDS:
>     words.append(item.strip('\n'))
> MEDWORDS = open("Med.txt","r+")
> words = []
> for item in MEDWORDS:
>     words.append(item.strip('\n'))
> 
> HARDWORDS = open("Hard.txt","r+")
> words = []
> for item in HARDWORDS:
>     words.append(item.strip('\n'))
> 
> INSANEWORDS = open("Insane.txt", "r+")
> words = []
> for item in INSANEWORDS:
>     words.append(item.strip('\n'))
> 
> ```
> 
> 

The best way to do this would probably be to use generator expressions, and encapsulate it into a function, like this:

```
def build_word_list(word_file):
    words = [item.strip("\n") for item in word_file]
    return words

```

You can then use it like this, assuming you've already defined `build_word_list`:

```
EASYWORDS = open("Easy.txt","r+")
MEDWORDS = open("Med.txt","r+")
HARDWORDS = open("Hard.txt","r+")
INSANEWORDS = open("Insane.txt", "r+")

easy_words = build_word_list(EASYWORDS)
medium_words = build_word_list(MEDWORDS)
hard_words = build_word_list(HARDWORDS)
insane_words = build_word_list(INSANEWORDS)

```

I've also fixed a pretty large bug. You were creating only *one* word list, which meant that regardless of what difficulty you chose, you'd have words from all difficulties. Now there are separate word lists for each separate difficulty.

---

Creating a `play` function
==========================

The functions `easy`, `med`, `hard` and `insane` are all identical. There is no reason that you should be repeating yourself over and over again. To help prevent the repetition, create one simple `play` function with an argument named `word_list`. The signature for the `play` function *should* look like this:

def play(word\_list):
 # Game logic goes here

You'd simply pass a word list, like `easy_words` or `insane_words` as the `word_list` argument, and then use the `word_list` argument in the function.

---

Misc. Nitpicks
==============

There are quite a few things I want to nitpick, so get ready.

* The `difficulty2` function serves no purpose. It is identical in every way to `difficulty`. Any calls to `difficulty2` in your code can just be changed to `difficulty` calls.
* Similarly to the above nitpick, your `difficultyEASY`, `difficultyMED`, etc. functions are *also* virtually identical. Simply create one function named `change_difficulty` and you're set.
* You need whitespace between your operators, and an introduction to [PEP8](https://www.python.org/dev/peps/pep-0008/), the official Python style guide.. Nobody wants to read code that looks like it was plucked straight out of a PPCG answer.
Word Storage
------------

1. Don't leave file handles open if you're done with them
Each time you `open()` a file, it allocates operating system and interpreter resources (*handles*). If you're done with a file, `close()` it!
2. You're actually **just making ONE huge word list** (**EDIT**: I see [@Ethan Bierlein](https://codereview.stackexchange.com/users/53251/ethan-bierlein) already pointed this out).
3. (Again, as [@Ethan Bierlein](https://codereview.stackexchange.com/users/53251/ethan-bierlein)'s answer goes to) You're repeating a LOT of similar code for your word lists.
Ethan's generator is a good idea here (just don't forget to `close()` those file-handles!

---

(Almost) Total repetition of game logic
---------------------------------------

The functions `easy`, `med`, `hard` and `insane` are 99% similar (okay I didn't calculate an actual percentage, but you know what I mean).
these can easily be accomplished with **MUCH** less code by making them more parameterised (*i.e.* taking an argument to a generated wordlist for difficulty).

---

Pythonic startup
----------------

Not that it's a huge deal for something like this, but if you want it to be more Pythonic, the last line:

> 
> `main()`
> 
> 
> 

Should be put inside an if statement to ensure the script isn't being used as a module, etc:

```
if __name__=='__main__':
    main()

```

This simply ensures `main` is only called if we are the *main* script in the interpreter.

---

String concatenation
--------------------

Also, not an \* end of the world \* thing, but (for example), the following line inside your `start` function:

> 
> `print ("Hello, " + name, "Time to play hangman! You have ten guesses to win!")`
> 
> 
> 

Uses *string concatenation* inside `print`. This is generally bad practise in Python. Instead, you should be using format strings:

`print ("Hello, %s, Time to play hangman! You have ten guesses to win!" % name)`

---

Needless if statements (and more code repetition)
-------------------------------------------------

I'm not sure what the purpose of the following if/elif block is (as they **both** have *exactly* the same code in them:

> 
> 
> ```
>        if fails == 1:
>             print ("You have", + fails, "fail....WATCH OUT!" )
>         elif fails >= 2 and fails < 10:
>             print ("You have", + fails, "fails....WATCH OUT!" )
>         if fails == 10:
> ...
> 
> ```
> 
> 

But they appear in EACH of the (many) game play functions.
This would much better be done with one `if` (and using a format string):

```
        if fails < 10:
            print ("You have %d fails....WATCH OUT!" % fails )
        else:
...

```

Also, note the *slight* logic difference here, the `else` is essentially all cases where `fails` is =>10, where as your code *just tests* ==10.