Single player Hangman in Python This program is yet to become user-friendly and is still in development, but I wanted to improve the current code.

from random import choice
from os import system

clear = lambda: system('cls') # FOR WINDOWS ONLY

words = [i.strip() for i in open('words.txt').readlines()]

# Possible stages
STAGES = [
"""






    -------
""",

"""
    _______
    |   |
    |
    |
    |
    |
    -------
""",

"""
    _______
    |   |
    |   O
    |
    |
    |
    -------
""",

"""
    _______
    |   |
    |   O
    |   |
    |
    |
    -------
""",


"""
    _______
    |   |
    |   O
    |  /|
    |
    |
    -------
""",

"""
    _______
    |   |
    |   O
    |  /|\\
    |
    |
    -------
""",

"""
    _______
    |   |
    |   O
    |  /|\\
    |  /
    |
    -------
""",

"""
    _______
    |   |
    |   O
    |  /|\\
    |  / \\
    |
    -------
"""]

class HangMan:
    def __init__(self):
        self.current_stage = 0                              # The stage in which the hangman is
        self.letters = [chr(i) for i in range(97, 97 + 26)] # Possible characters
        self.word = choice(words)                           # Random word
        self.current_word = ['_'] * len(self.word)          # The letters which the player has unlocked till now

    def get_input(self) -&gt; int:
        """ Takes the player's input and processes it """

        print(*self.letters)
        print()

        char = input('Please enter a letter from the above set: ')

        while char.lower() not in self.letters:
            print(f'Invalid letter: {char}\n')
            char = input('Please enter another letter: ')

        print()
        return self.process_char(char)

    def process_char(self, given_char: str) -&gt; int:
        """

        Processes the input and returns 0, 1, or 2

        0 -&gt; Win
        1 -&gt; Neither a win nor a loss
        2 -&gt; Lose

        """

        self.letters.remove(given_char.lower())
        unlocked = 0

        for index, char in enumerate(self.word):
            if char.lower() == given_char.lower():
                self.current_word[index] = char
                unlocked += 1

        if '_' not in self.current_word:
            print('You\'ve won!')
            return 0

        if not unlocked:
            print('Whoops! Wrong letter!')

            if not self.next_stage():
                clear()
                print(STAGES[self.current_stage])
                print('You\'ve lost!')
                return 2
        else:
            print(f'Yay! You\'ve unlocked {unlocked} letter{"" if unlocked == 1 else "s"}!')

        return 1

    def next_stage(self) -&gt; bool:
        """ Returns if this stage is the last """

        self.current_stage += 1

        if self.current_stage &lt; len(STAGES) - 1:
            return True

        return False

    def game(self) -&gt; None:
        """ Starts the game """

        while True:
            clear() # Comment if you are not using a command console

            print('Currently unlocked letters:', ''.join(self.current_word))
            print()
            print(STAGES[self.current_stage])

            x = self.get_input()

            if x == 0 or x == 2:
                print(f'The word was {self.word}!')

            print()
            input('Press enter to continue...')

            if x == 0 or x == 2:
                return

man = HangMan()

man.game()


How do I improve this? (Make this look better, make it faster, etc.)
Your code is good but it may be overly complex. The more concise the code the easier it is to read (for me anyway). In this example below I have just used some example words, this code of course is just a quick example for demonstration. There is not anything in place if you get the word or want to guess the word etc. I couldn't really find a reason to use a class for simpler games because although the functions are 'closely related' in your functions, comprehension can save a lot of time and code. 

The while loop is useful because it gives a consistent input option which can be as user friendly as you make it. I think its essential for the users experience when making something like a text RPG. 

import random

words = ['cheese', 'biscuits', 'hammer', 'evidence'] 
word_choice = [i.lower() for i in random.choice(words)]
lives = 3
cor_guess = []
while True:
  print('Letters found: {}\nWord length: {}'.format(cor_guess, len(word_choice)))
  if lives == 0:
      print('Your dead homie!\nThe word was: ', word_choice)
      break
  guess = str(input('Guess a letter: '))
  if guess in word_choice:
      print(guess, 'is in the word!\n')
      cor_guess.append(guess)
  else:
      print('Your dying slowly!\n')
      lives -= 1


Example of the output:

Letters found: []
Word length: 8
Guess a letter: v
v is in the word!

Letters found: ['v']
Word length: 8
Guess a letter: i
i is in the word!

Letters found: ['v', 'i']
Word length: 8
Guess a letter: r
Your dying slowly!

Letters found: ['v', 'i']
Word length: 8
Guess a letter: b
Your dying slowly!

Letters found: ['v', 'i']
Word length: 8
Guess a letter: o
Your dying slowly!

Letters found: ['v', 'i']
Word length: 8
Your dead homie!
The word was:  ['e', 'v', 'i', 'd', 'e', 'n', 'c', 'e']