Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
426: Building a Hangman Game
Alright, let's build something tangible. We're making a Hangman game. I've got the basics of loops and lists down from previous lessons, but putting them together into a game loop is where things usually get messy. I'll build this out loud with you, and we'll fix the bugs as they pop up.
Masking the Secret Word
First, I need a word. I'll keep it simple and just hardcode one for now—let's go with "pythonic". The challenge is that I can't just show the word to the player. I need to show underscores for letters they haven't guessed yet. My first instinct is to create a list of underscores.
word = "pythonic"
guesses = []
display = ["_"] * len(word)
print(display) # Output: ['_', '_', '_', '_', '_', '_', '_', '_']
That looks right, but printing a Python list looks ugly with the brackets and commas. I want it to look like _ _ _ _ _ _ _ _. I'll use "".join(), but I'll add a space for readability.
print(" ".join(display)) # Output: _ _ _ _ _ _ _ _
The Logic Gap
Now I need to let the user guess a letter. I'll wrap this in a while loop so the game keeps going until they win or run out of turns. Let's try a basic version where we just check if the letter is in the word.
word = "pythonic"
guesses = []
lives = 6
while lives > 0:
guess = input("Guess a letter: ").lower()
if guess in word:
print("Correct!")
else:
print("Wrong!")
lives -= 1
Wait, I just realized something. I'm telling them if they're correct, but I'm not actually updating those underscores. The game is basically useless right now because the "board" never changes. I need to loop through the original word and, if the character matches the guess, update the display list at that exact index.
# Inside the 'if guess in word:' block:
for index in range(len(word)):
if word[index] == guess:
display[index] = guess
Handling the "Double Guess" Frustration
I just ran this and noticed a annoying bug: if I guess 'p' twice, the game tells me "Correct!" both times, but it doesn't actually progress anything. Even worse, if I guess a wrong letter twice, I lose two lives for the same mistake. That's poor UX.
I should check if the letter is already in my guesses list before I do anything else. If it is, I'll just tell the user they've already tried that one and skip the rest of the loop using continue.
if guess in guesses:
print("You already guessed that!")
continue
guesses.append(guess)
Defining the Finish Line
Last piece of the puzzle: how does the game end? Right now, the loop only stops when lives hits 0. But what if they guess the word perfectly? They'd be stuck in the loop forever unless I manually crash the program.
I have two options: I could track how many letters are left to guess, or I can simply check if there are any underscores left in the display list. Checking for underscores is cleaner. If "_" not in display, they've won.
Here is how the final logic flows together:
word = "pythonic"
display = ["_"] * len(word)
guesses = []
lives = 6
while lives > 0 and "_" in display:
print(f"\nWord: {' '.join(display)} | Lives: {lives}")
guess = input("Guess a letter: ").lower()
if len(guess) != 1 or not guess.isalpha():
print("Please enter a single letter.")
continue
if guess in guesses:
print("Already guessed that!")
continue
guesses.append(guess)
if guess in word:
for i in range(len(word)):
if word[i] == guess:
display[i] = guess
else:
lives -= 1
print("Wrong!")
if "_" not in display:
print(f"\nCongrats! You found the word: {word}")
else:
print(f"\nGame over! The word was: {word}")
I added a small check for isalpha() and length because users love to press Enter without typing anything or type "123" just to see if the program crashes. Always assume the user will try to break your input.
📋 Practical Task
Adding a Word Bank to Hangman
Currently, the game uses a single hardcoded word ("pythonic"). To make this a real game, you need to randomize the word each time it starts.
- Import the
randommodule at the top of your script. - Create a list called
word_bankcontaining at least five different words. - Replace the
word = "pythonic"line with a call torandom.choice()to pick a random word from your list. - Run the game multiple times to ensure the
displaylist and the win/loss logic adapt correctly to words of different lengths.
There are no comments for now.