Lecture 02: Project - Let's Build "Guess the Number"!

Lecture 02: Project - Let’s Build “Guess the Number”!

Welcome back, coders! In our first lecture, we took a gentle stroll into the world of coding. We learned that coding is essentially giving step-by-step instructions to a computer, and we saw how Python is a language that helps us do this in a readable way. We also got a tiny peek at Python with variables (our labeled boxes for storing information), the print() function (for showing messages on the screen), and the input() function (for getting information from the user).

Today, we’re going to take those basic ingredients and cook up something much more exciting: our very first complete game! We’ll be building a classic game called “Guess the Number.” This project will be a fantastic way to see how these simple Python concepts can be combined to create something fun and interactive. Along the way, we’ll also learn some new and powerful tools that Python offers for controlling the flow of our programs and handling potential surprises. Let’s get started!

What We’re Building: The “Guess the Number” Game

The “Guess the Number” game is a simple yet engaging programming challenge that you’ll find in many coding tutorials because it beautifully illustrates several core concepts. Here’s the basic idea of how it works:

  1. The Setup: The computer will secretly “think” of a random whole number within a specific range (for example, any number between 1 and 100).
  2. The Challenge: It will then tell you (the player) that it has thought of a number and will ask you to guess what that number is.
  3. The Feedback Loop:
    • If your guess is too high, the computer will politely inform you, “Too high! Try again.”
    • If your guess is too low, it will say, “Too low! Try again.”
  4. Keep Guessing: You continue to make guesses, and the computer continues to give you feedback, until you finally guess the secret number correctly!
  5. The Victory: When you guess the right number, the computer will congratulate you and also tell you how many attempts it took you to find the secret.

Sounds like a fun challenge, doesn’t it? Building this game will involve a bit of logic, some repetition, and handling user input – all great things to learn!

Key Concepts We’ll Use

To build our “Guess the Number” game, we’ll be using the Python concepts we’ve already touched upon, plus a few new and very important ones:

  • Variables: We’ll definitely need these! We’ll use variables to store the computer’s secret number, the player’s current guess, and to keep track of how many attempts the player has made. (Remember these from Lecture 01? They’re our labeled boxes!)
  • input() function: To get the player’s guess from them when they type it.
  • print() function: To give messages and feedback to the player (like “Too high!”, “Too low!”, or “Congratulations!”).
  • Modules & Random Numbers (New!): How does the computer “think” of a number randomly? Python has built-in “toolboxes” called modules that provide extra functionalities. We’ll import and use the random module to generate a random secret number.
  • Loops (Specifically, while loops - New!): How do we allow the player to keep guessing multiple times until they get it right? A while loop will let us repeat a block of code as long as a certain condition is true (or, in our game’s case, until a certain condition is met).
  • Conditional Logic (if/elif/else - New!): How do we check if the player’s guess is too high, too low, or exactly correct? We’ll use if, elif (else if), and else statements to make these decisions and run different code accordingly.
  • Error Handling (try-except - New!): What if the user types something that isn’t a number when we ask for their guess (e.g., they type “hello” or “five”)? Our program might crash! We’ll learn to use a try-except block to gracefully handle such situations and ask the user for valid input.

It might seem like a lot, but we’ll go through each new concept carefully.

Understanding the Building Blocks (New Concepts in Detail)

Before we dive into the full code for the “Guess the Number” game, let’s take a moment to understand these new Python tools – modules, while loops, if/elif/else, and try-except – with some simpler, standalone examples. This will make it easier to see how they work when we put them all together in our game.

Modules: Python’s Toolboxes (like import random)

Imagine you have a big toolbox, and inside it, you have smaller, specialized toolkits. One toolkit might be for plumbing, another for electrical work, and another for woodworking. You wouldn’t carry every single tool you own all the time, right? You’d just grab the specific toolkit you need for the job at hand.

A module in Python is very much like one of those specialized toolkits.

  • What it is: A module is a file containing Python definitions (like functions and variables) and statements that provide extra functionality. Python comes with a vast “standard library” full of these modules (toolboxes) for common tasks, like working with math (math module), dates and times (datetime module), or, as we’ll use, generating random numbers (random module).
  • Purpose:
    • Organization: Modules help keep Python code organized by grouping related functions and tools together.
    • Reusability: You can use the functions from a module in many different programs without having to rewrite that code yourself.
    • Extending Python: They extend the core capabilities of Python.
  • How import works: To use the tools from a module in your program, you first have to “bring it in” or “load it.” This is done using the import keyword.
    • For example, the line import random tells Python: “Hey, I need to use some tools from the ‘random’ toolkit. Please make them available to my program.”

Simple random.randint(a, b) Example:
Once you’ve imported the random module, you can use the functions it contains. One very useful function in the random module is randint(a, b).

  • randint stands for “random integer.”
  • It takes two numbers, a and b, as input (arguments).
  • It then returns a random whole number that is greater than or equal to a and less than or equal to b (it’s an inclusive range, meaning a and b themselves could be chosen).

Let’s see it in action:

import random # Step 1: Bring in the 'random' toolbox.

# Step 2: Use a function from the toolbox.
# Simulate rolling a standard 6-sided die.
# random.randint(1, 6) will give us a random whole number between 1 and 6 (inclusive).
dice_roll_result = random.randint(1, 6)
print("You rolled a die and got:", dice_roll_result)

# Another example: Pick a random lucky number between 50 and 100
lucky_number = random.randint(50, 100)
print("Your lucky number for today is:", lucky_number)

If you run this code multiple times, you’ll likely see different numbers printed for dice_roll_result and lucky_number each time because randint() picks randomly from the range you specify! This randomness is exactly what we need for our game’s secret number.

Repeating Actions: while Loops

Sometimes, you want your program to do the same thing (or a similar set of things) over and over again. For example, in our game, we want to keep asking the player for a guess until they guess correctly. This is where loops come in.

A while loop is one type of loop in Python. It’s designed to repeatedly execute a block of code as long as a certain condition remains True.

  • Purpose: To automate repetitive tasks when you want the repetition to continue based on a condition.
  • How it works:
    1. Python first checks the condition specified in the while statement.
    2. If the condition is True, the indented block of code (the “loop body”) is executed.
    3. After the loop body finishes, Python goes back up to the while statement and checks the condition again.
    4. If the condition is still True, the body executes again. This process repeats.
    5. If the condition becomes False when Python checks it, the loop stops, and the program continues with the code immediately after the loop body.

Simple while Loop Example: Counting from 1 to 5
Let’s see how to use a while loop to print numbers from 1 to 5.

# Example: Count from 1 to 5 using a while loop
current_number = 1  # 1. Initialize a variable to start our count.

# 2. Set up the loop condition: Keep looping as long as 'current_number' is less than or equal to 5.
while current_number <= 5:
    # 3. This is the loop body (the code that gets repeated):
    print("Current number is:", current_number)

    # 4. Crucial step: Update the variable that the condition depends on.
    #    We increase 'current_number' by 1 in each iteration.
    #    current_number = current_number + 1  (This is the same as current_number += 1)
    current_number += 1
    # After this, Python goes back to check 'while current_number <= 5:' again.

# 5. This line is executed only after the loop condition becomes false (i.e., when current_number becomes 6).
print("Loop finished counting!")

Explanation of the counter example:

  • current_number = 1: We start with current_number being 1.
  • First check: 1 <= 5 is True. So, the loop body runs:
    • Prints “Current number is: 1”.
    • current_number becomes 1 + 1 = 2.
  • Second check: 2 <= 5 is True. Loop body runs:
    • Prints “Current number is: 2”.
    • current_number becomes 2 + 1 = 3.
  • This continues until…
  • Fifth check: 5 <= 5 is True. Loop body runs:
    • Prints “Current number is: 5”.
    • current_number becomes 5 + 1 = 6.
  • Sixth check: 6 <= 5 is now False! So, the loop stops, and Python executes print("Loop finished counting!").

The line current_number += 1 is absolutely vital. If we forgot it, current_number would always stay at 1, the condition current_number <= 5 would always be true, and the loop would run forever! This is called an infinite loop, and it’s a common mistake for beginners.

while True: for Our Game:
Sometimes, like in our “Guess the Number” game, we want a loop to run indefinitely until a specific event happens inside the loop (like the player guessing correctly). For this, we can use while True:.
True is always, well, true! So, a while True: loop will run forever unless something inside the loop explicitly tells it to stop. The command to stop a loop from within is break. We’ll see this in our game code. It’s a useful pattern when you don’t know the exact number of repetitions beforehand.

Making Decisions: if, elif, else

Programs often need to make choices and execute different pieces of code based on whether certain conditions are met. For example, our game needs to decide whether the guess is too high, too low, or correct. This is where conditional statementsif, elif (which stands for “else if”), and else – come into play.

  • Purpose: To control the flow of your program, allowing it to execute specific blocks of code only when certain conditions are true.

Simple if/else Example: Checking Age

age = 15

# The 'if' statement checks a condition.
if age >= 18:
    # This block of code runs ONLY if the condition (age >= 18) is True.
    print("You are considered an adult.")
else:
    # This block of code runs ONLY if the condition (age >= 18) is False.
    print("You are considered a minor.")

In this example, since age is 15, the condition 15 >= 18 is False. So, Python skips the if block and executes the code inside the else block, printing “You are considered a minor.”

Simple if/elif/else Example: Checking Temperature
You can check multiple conditions in a sequence using if, elif (as many elifs as you need), and an optional else at the end. Python will execute the block of code for the first condition that it finds to be true, and then it will skip all the other elif and else blocks in that chain.

temperature = 22 # in Celsius

if temperature > 30:
    print("It's quite hot today!")
elif temperature > 20: # This is checked only if 'temperature > 30' was False.
    print("The weather is pleasantly warm.")
elif temperature < 10: # This is checked only if both previous conditions were False.
    print("It's quite cold!")
else: # This runs if NONE of the preceding if/elif conditions were True.
    print("The temperature is moderate.")

In this case:

  1. Is temperature > 30 (i.e., 22 > 30)? No, it’s False.
  2. So, Python checks the next elif: Is temperature > 20 (i.e., 22 > 20)? Yes, it’s True!
  3. Python executes print("The weather is pleasantly warm.").
  4. Because it found a true condition, it skips the remaining elif temperature < 10: and the else: block entirely.
    Only one block in an if/elif/.../else chain will ever be executed.

Handling Mistakes Gracefully: try and except ValueError

When we ask the user for input, especially when we expect a number, they might type something unexpected. For example, if we ask for their guess (a number) and they type “hello” or “fifty” or even just press Enter without typing anything.
If our code then tries to convert this non-numeric input directly into an integer using int(), like guess = int(user_input), Python will encounter an error (specifically, a ValueError) and the program will crash, showing an error message to the user. This isn’t very user-friendly!

The try and except statements in Python allow us to anticipate and handle these potential errors (called “exceptions”) gracefully, preventing our program from crashing.

  • Purpose: To “try” running a block of code that might cause an error. If a specific error occurs, the code in the “except” block is executed, instead of the program crashing.
  • Focus on int() Conversion and ValueError: A very common place where errors occur is when converting user input (which input() always gives us as text/string) to a number using int() (for whole numbers) or float() (for numbers with decimals). If the string doesn’t look like a valid number that can be converted, int() or float() will raise a ValueError.

Simple try-except Example:
Let’s try to get the user’s age and convert it to an integer.

print("Let's try to get your age.")
try:
    # Code that MIGHT cause an error goes in the 'try' block.
    age_text = input("Please enter your age (as a number): ")

    # This is the risky line:
    age_number = int(age_text)

    # This line will ONLY run if the int() conversion above was successful:
    print("Great! Next year, you will be", age_number + 1, "years old.")

except ValueError:
    # Code in this 'except ValueError:' block runs ONLY IF a ValueError
    # occurred inside the 'try' block (e.g., if int(age_text) failed).
    print("Oops! That doesn't look like a valid whole number. Please type digits like '25'.")

print("Program continues after the try-except block.")

How it works:

  1. Python enters the try block.
  2. It executes age_text = input(...). Let’s say the user types “hello”. So, age_text becomes "hello".
  3. Then, Python attempts age_number = int(age_text), which is age_number = int("hello"). This conversion is impossible, so Python raises a ValueError internally.
  4. Because a ValueError occurred, Python immediately jumps out of the try block (the print("Great! Next year...") line is skipped) and looks for an except ValueError: block.
  5. It finds one, so it executes the code inside that except block: print("Oops! ...").
  6. After the except block finishes, the program continues normally with the code after the try-except structure (print("Program continues...")). The program didn’t crash!

If the user had typed “30”, then int("30") would succeed, age_number would become 30, the “Great! Next year…” message would print, and the except ValueError: block would be skipped entirely.

This try-except mechanism is a powerful way to make your programs more robust and user-friendly by anticipating and managing potential errors.

Now that we’ve explored these fundamental building blocks – importing modules, using while loops for repetition, if/elif/else for decisions, and try-except for error handling – we’re much better prepared to understand the full code for our “Guess the Number” game!

Let’s Look at the Code!

We’ll be creating a Python file for our game. Let’s imagine we save it as guess_the_number_game.py, and following good practice, we might put it inside a folder structure like examples/guessing_game/. So the full path could be examples/guessing_game/guess_the_number_game.py.

Here’s the complete code for our game. We’ll break it down section by section right after.

# examples/guessing_game/guess_the_number_game.py

# Import the random module to generate random numbers
import random

def guess_the_number():
    """Plays the 'Guess the Number' game with the user."""

    # Generate a random secret number between 1 and 100 (inclusive)
    # This is the number the player has to guess.
    secret_number = random.randint(1, 100)

    # Initialize a variable to keep track of how many guesses the player has made.
    attempts = 0

    # Welcome messages for the player.
    print("Welcome to the Guess the Number Game!")
    print("I'm thinking of a number between 1 and 100.")

    # Start the main game loop. This loop will continue until the player guesses correctly.
    # We learned about 'while True:' earlier – it runs indefinitely until a 'break' statement.
    while True:
        # This 'try-except' block will handle cases where the user doesn't enter a valid number.
        # We discussed this in "Handling Mistakes" with try and except.
        try:
            # Prompt the user for their guess. input() returns the user's typed text.
            guess_str = input("Take a guess: ")

            # Convert the user's input string into an integer (a whole number).
            # This is where a ValueError might happen if the user types non-digits.
            guess = int(guess_str)

            # Increment the attempts counter.
            # attempts += 1 is shorthand for attempts = attempts + 1
            attempts += 1

            # Check the guess using conditional logic (if/elif/else).
            if guess < secret_number:
                # If the guess is too low, tell the player.
                print("Too low! Try again.")
            elif guess > secret_number:
                # If the guess is too high, tell the player.
                print("Too high! Try again.")
            else:
                # If the guess is not too low AND not too high, it must be correct!
                # The f"" syntax is an f-string, a convenient way to put variables in strings.
                print(f"Congratulations! You guessed the number {secret_number} correctly!")
                print(f"It took you {attempts} attempts.")

                # Since the guess is correct, we need to stop the loop.
                # The 'break' statement immediately exits the 'while True' loop.
                break

        except ValueError:
            # This code runs ONLY if the int(guess_str) line caused a ValueError.
            print("Oops! That doesn't look like a number. Please enter a valid whole number.")
            # After printing this message, the 'continue' statement (which is implicitly here
            # as it's the end of the except block within the while loop) will cause the
            # loop to go back to the 'input("Take a guess: ")' part for the next iteration.

# This is a standard Python pattern to make the game run when the script is executed directly.
if __name__ == "__main__":
    # This calls our main game function to start the game.
    guess_the_number()

Breaking Down the Code (Section by Section)

Let’s go through the code piece by piece to understand exactly what each part does and why it’s there.

  1. import random

    import random
    
    • Why: Our game needs the computer to pick a secret number randomly. Python doesn’t just “know” how to do randomness by default for everything. This functionality is packaged in the random module.
    • How: The import random statement tells Python to load its built-in random module (like getting the “random tools” toolkit from Python’s standard library). Once imported, we can use functions defined within this module, like random.randint(). This is exactly what we discussed in the “Modules: Python’s Toolboxes” section.
  2. def guess_the_number():

    def guess_the_number():
        """Plays the 'Guess the Number' game with the user."""
        # ... all the game logic will be indented inside this function ...
    
    • Why: We’re organizing our entire game’s code into a function called guess_the_number. This is good practice for several reasons:
      • Organization: It groups all related game logic together.
      • Reusability (Conceptual): While we’ll only call it once here, in larger programs, you might want to restart a game or call it from different places.
      • Clarity: It gives a clear name to the block of code that runs the game.
    • How: def guess_the_number(): defines the function. The """Docstring""" explains what the function does. All the code for the game will be indented underneath this line.
  3. Setting up the Game (Inside guess_the_number()):

    secret_number = random.randint(1, 100)
    attempts = 0
    
    print("Welcome to the Guess the Number Game!")
    print("I'm thinking of a number between 1 and 100.")
    
    • secret_number = random.randint(1, 100)
      • Why: The computer needs to choose a secret number for the player to guess. This number should be different each time the game is played to keep it interesting.
      • How: It calls random.randint(1, 100). As we learned, randint(a, b) (from the random module we imported) picks a random integer between a and b, including a and b themselves. So, this line picks a random whole number from 1 to 100 (inclusive) and stores it in the variable secret_number. The computer now “remembers” this number, but the player doesn’t know it yet!
    • attempts = 0
      • Why: We want to tell the player how many tries it took them to guess the number. So, we need a counter.
      • How: We create a variable named attempts and initialize its value to 0. This variable will be incremented each time the player makes a guess.
    • print(...) statements:
      • Why: To provide a friendly welcome to the player and explain the basic premise of the game.
      • How: Standard print() functions display these messages on the screen.
  4. The Main Game Loop: while True:

    while True:
        # ... code for getting a guess and checking it ...
    
    • Why: The game needs to repeatedly ask the player for a guess until they get it right. We don’t know in advance if it will take 1 guess, 5 guesses, or 20 guesses! A loop is needed for this repetition.
    • How: while True: creates an infinite loop – a loop that, on its own, would run forever because the condition True is always true. We use this pattern, as discussed in the “Building Blocks” section on while loops, because the condition to stop the loop (guessing the correct number) is checked inside the loop. When that condition is met, we will use a break statement to exit the loop.
  5. Getting the Player’s Guess (Inside the while loop, within the try block):

        try:
            guess_str = input("Take a guess: ")
            guess = int(guess_str)
            attempts += 1
    
    • guess_str = input("Take a guess: ")
      • Why: We need to get the player’s guess.
      • How: The input() function displays the prompt "Take a guess: " on the screen, then pauses and waits for the user to type something and press Enter. Whatever the user types is returned as a string (text) and stored in the variable guess_str.
    • guess = int(guess_str)
      • Why: The input() function always gives us a string. But the secret_number is an integer, and we need to compare the guess with it numerically (e.g., is it higher or lower?). So, we must try to convert the user’s input string into an integer.
      • How: The int() function attempts this conversion. If guess_str contains characters that look like a whole number (e.g., “10”, “75”), int() will convert it into an actual integer, which is then stored in the guess variable. If guess_str contains non-digits (e.g., “hello”, “twenty”), int() cannot convert it and will raise a ValueError. This line is placed inside the try block because it’s a “risky” operation that might cause an error.
    • attempts += 1
      • Why: We need to count each valid guess attempt.
      • How: attempts += 1 is a shorthand way of writing attempts = attempts + 1. It takes the current value of attempts, adds 1 to it, and stores the new value back into attempts. This happens after we’ve successfully converted the input to an integer, meaning it was a valid attempt.
  6. Handling Potential Input Errors (The except block):

        except ValueError:
            print("Oops! That doesn't look like a number. Please enter a valid whole number.")
            # continue (implicitly, the loop will continue to the next iteration)
    
    • Why: If the user types something like “hello” when asked for a number, int(guess_str) in the try block will fail and raise a ValueError. Without the try-except block, this error would crash our program. We want to handle it gracefully.
    • How: If a ValueError occurs anywhere inside the try block, Python immediately jumps to the except ValueError: block. The code here prints a helpful message to the user. After the except block finishes, the while loop naturally continues to its next iteration (it will ask for input again), effectively giving the user another chance to enter a valid number. The continue keyword (which we saw in the “Building Blocks” section for try-except) could be used here explicitly, but since the except block is at the end of the while loop’s iteration, the loop will continue to the next iteration anyway.
  7. Checking the Guess (Inside the try block, after successful input conversion):

            if guess < secret_number:
                print("Too low! Try again.")
            elif guess > secret_number:
                print("Too high! Try again.")
            else:
                # ... (congratulations and break) ...
    
    • Why: This is the core game logic! We need to compare the player’s guess with the computer’s secret_number and give appropriate feedback.
    • How: We use an if/elif/else conditional structure, which we learned about in the “Building Blocks” section.
      • if guess < secret_number:: If the guess is too low, print “Too low! Try again.”
      • elif guess > secret_number:: If the first condition was false (guess is not too low) and the guess is too high, print “Too high! Try again.”
      • else:: If neither of the above conditions was true, it means the guess must be equal to secret_number! The player has won.
  8. Handling a Correct Guess (Inside the else part of checking the guess):

            else: # (This means guess == secret_number)
                print(f"Congratulations! You guessed the number {secret_number} correctly!")
                print(f"It took you {attempts} attempts.")
                break
    
    • Why: When the player guesses correctly, we need to congratulate them, tell them their score (number of attempts), and end the game.
    • How:
      • print(f"..."): We use f-strings (formatted string literals) to print messages that include the values of variables like secret_number and attempts directly within the string. F-strings are very convenient for this!
      • break Statement: This is crucial. The break keyword immediately terminates the innermost loop it’s in. In this case, it stops the while True: game loop. Since the player has guessed the number, we don’t need to ask for any more guesses. The program execution will then jump to whatever code comes after the while loop (in this case, the end of the guess_the_number function).
  9. Running the Game (The if __name__ == "__main__": block):

    if __name__ == "__main__":
        guess_the_number()
    
    • Why: We want our game to start automatically when we run this Python file, but not if we were to import this file as a module into another script (a more advanced concept we’ll touch on later).
    • How: This is a standard Python idiom.
      • When you run a Python file directly (e.g., by typing python guess_the_number_game.py in your terminal), Python automatically sets a special internal variable called __name__ to the string value "__main__".
      • So, the condition if __name__ == "__main__": becomes true.
      • Consequently, the code inside this block, guess_the_number(), is executed, which calls our main game function and starts the game.
      • If this file were imported as a module into another Python script, __name__ would be set to the module’s name (i.e., “guess_the_number_game”), so the condition would be false, and guess_the_number() would not be called automatically (which is usually what you want when importing).

This detailed breakdown should help you see how each piece of the code contributes to the overall functionality of the “Guess the Number” game, and how it uses the Python concepts we’ve been learning!

How to Play Your Game

Once you have the code saved in a file (e.g., examples/guessing_game/guess_the_number_game.py), here’s how you can play it:

Option 1: Using a Terminal / Command Prompt

  1. Save the Code: Ensure the Python code above is saved in a file named guess_the_number_game.py within an examples/guessing_game/ directory structure (or any location you prefer).
  2. Open a Terminal or Command Prompt:
    • On Windows, you can search for “Command Prompt” or “PowerShell”.
    • On macOS, search for “Terminal” (usually in Applications > Utilities).
    • On Linux, you likely know how to open your terminal (Ctrl+Alt+T is common).
  3. Navigate to the Directory: Use the cd (change directory) command to go to the folder where you saved your Python file.
    • For example, if your project is in a folder like MyPythonProjects/Lecture02/examples/guessing_game/ on your Desktop, you might type something like:
      cd Desktop/MyPythonProjects/Lecture02/examples/guessing_game/
      (The exact command depends on where you saved it and your operating system).
  4. Run the Game: Once your terminal is in the correct directory, type the following command and press Enter:
    python guess_the_number_game.py
    (If you have multiple Python versions, you might need to use python3 instead of python).
  5. Follow the Prompts: The game will start in your terminal! It will print “Welcome…” and then "Take a guess: ". Type your number and press Enter. Continue until you guess the number.

Option 2: Using Google Colaboratory (Colab) or an Online Python Interpreter

If you don’t want to set up Python locally yet, online tools are great!

  1. Open Google Colab: Go to https://colab.research.google.com/. You might need to sign in with a Google account.
  2. Create a New Notebook:
    • Click “File” → “New notebook”. This will open a new, blank Python programming environment in your browser.
  3. Get the Game Code: Copy the entire Python code for our “Guess the Number” game from the code block provided earlier in this lecture.
  4. Add a Code Cell: Your new Colab notebook will likely already have an empty “code cell.” It looks like a box where you can type code, with a little “play” button icon (a circle with a triangle) to its left. If you don’t see one, or need a new one, click + Code in the top left menu bar.
  5. Paste the Code: Click inside the empty code cell and paste the entire game code into it.
  6. Run the Code:
    • To run the game, you can either click the “play” button to the left of the code cell.
    • Or, while your cursor is inside the code cell, press Shift + Enter on your keyboard.
  7. Play the Game!
    • After you run the cell, the game will start!
    • The welcome message (“Welcome to the Guess the Number Game!”) and the input prompt ("Take a guess: ") will appear below the code cell.
    • Type your guess in the box provided in that output area and press Enter.
    • The game will continue to interact with you in this area below the code cell.

That’s it! Using an online tool like Colab is a fantastic way to experiment with Python code quickly without worrying about local installation setups, especially when you’re getting started.

Next Steps & Challenges (Optional Fun!)

Now that you have a working “Guess the Number” game, you might be thinking of ways to improve it or challenge yourself further. This is what programming is all about – building something and then making it better! Here are some ideas (you don’t have to do these now, but they are great for practice later):

  1. Limit the Number of Guesses:

    • Challenge: Can you change the game so the player only gets a fixed number of guesses, say, 7 or 10?
    • If they guess the number within the allowed tries, they win as usual.
    • If they run out of guesses and haven’t found the number, the game should tell them they’ve lost and perhaps reveal what the secret number was.
    • Hint: You’ll need to use your attempts variable. Your while loop condition might need to change (e.g., while attempts < max_attempts:), or you could add an if statement inside the loop to check if attempts has reached the limit and then use break if it has, along with a “you lost” message.
  2. Let the Player Choose the Range:

    • Challenge: Instead of the computer always picking a number between 1 and 100, could you ask the player at the beginning of the game to enter the minimum and maximum numbers for the guessing range?
    • For example, they might want to guess a number between 1 and 50, or between 100 and 200.
    • The game should then use these user-defined numbers when picking the secret_number with random.randint().
    • Hint: You’ll need two input() calls at the start of your guess_the_number function. Remember that input() gives you strings, so you’ll need to convert these to integers using int() (and maybe use try-except to handle cases where the user doesn’t type valid numbers for the range). Make sure random.randint() then uses these new variables.
  3. Play Again Feature:

    • Challenge: After a game ends (whether the player wins or loses), could you ask them if they want to play again?
    • If they type “yes” (or maybe just “y”), the entire game should start over with a new secret number and reset attempts.
    • If they type anything else (like “no” or “n”), the program should print a friendly “Thanks for playing!” message and then end.
    • Hint: You might need another while loop that goes around most of your current game logic (including the part where secret_number is generated and attempts is reset). The condition for this outer loop would depend on whether the player wants to play again.
  4. Difficulty Levels:

    • Challenge: Could you offer different difficulty levels (e.g., “easy”, “medium”, “hard”) at the start of the game?
    • Each difficulty level could change the range of numbers (e.g., easy is 1-50 with 10 guesses, medium is 1-100 with 7 guesses, hard is 1-200 with 5 guesses).
    • Hint: Ask the user for their difficulty choice. Then use if/elif/else statements to set the max_range for random.randint() and perhaps a max_attempts variable based on their choice.
  5. More Specific Feedback (A Bit More Advanced):

    • Challenge: Instead of just “Too high!” or “Too low!”, could you give the player a hint if they are getting “warmer” (closer to the secret number than their last guess) or “colder” (further away)?
    • Hint: This is trickier! You’d need to store the player’s previous guess. Then, after they make a new guess, you’d compare the difference between the new guess and the secret number with the difference between the previous guess and the secret number. (The abs() function, which gives the absolute value of a number, is very helpful here for calculating differences regardless of whether the guess is too high or too low).

Congratulations on building your first complete game project! By understanding this code, playing with it, and maybe even trying some of these challenges, you’re taking huge steps in your coding journey. Remember, the more you practice and experiment, the more comfortable you’ll become. Most importantly, have fun with it!

Concepts Learned in This Lecture

This lecture, centered around the “Guess the Number” game project, introduced you to several important and foundational Python concepts. Let’s recap what you’ve encountered:

  • Modules and import: You learned that modules are like Python’s “toolboxes” containing pre-written code (e.g., the random module for random number generation). You use the import statement to make these tools available in your program.
  • Using Module Functions: You specifically used random.randint(a, b) to get the computer to pick a random whole number within an inclusive range [a, b].
  • while Loops: You saw how while loops are used to repeat a block of code as long as a certain condition is True. We used while True: to create a loop that continues indefinitely until explicitly exited with a break statement, which is perfect for game loops where the number of repetitions isn’t known in advance.
  • User Input with input(): You used the input() function to get text (string) input from the player when they make their guess.
  • Type Conversion with int(): You learned that input() always returns a string, and if you need to treat that input as a whole number (an integer) for comparisons or calculations, you must convert it using int().
  • Conditional Logic (if/elif/else): You used these statements extensively to make decisions in the game – specifically, to check if the player’s guess was less than, greater than, or equal to the secret_number, and to provide the appropriate feedback.
  • Error Handling (try-except ValueError): You learned how to use try-except blocks to gracefully handle potential errors. In our game, this was crucial for catching ValueErrors that occur if the player types something non-numeric when int() tries to convert their guess. This prevents the program from crashing.
  • break Statement: You saw how the break statement is used to immediately exit the current loop (our while True: game loop) once the player guesses the number correctly.
  • f-strings (Formatted String Literals): You encountered f-strings (e.g., f"Congratulations! You guessed the number {secret_number} correctly!") as a convenient and readable way to embed the values of variables directly inside your printed messages.
  • Defining Functions (def): The entire game logic was encapsulated within a function def guess_the_number():. This helps in organizing the code into a logical unit.
  • Calling Functions: You learned that to execute the code inside a function, you “call” it by using its name followed by parentheses (e.g., guess_the_number()).
  • The if __name__ == "__main__": block: You were introduced to this standard Python construct, which ensures that code within it (like the call to guess_the_number() to start the game) only runs when the file is executed directly, not when it’s imported as a module into another script.

Phew, that’s quite a list of powerful concepts packed into one game! Don’t worry if not everything is 100% crystal clear right away. The more you see these concepts in different contexts and the more you practice using them yourself, the more familiar and intuitive they will become. Keep coding, keep experimenting, and keep asking questions!

Homework Challenges

Ready to practice your new skills and make the “Guess the Number” game even more awesome? Here are some challenges. Pick one or two that seem interesting to start with, or try them all if you’re feeling adventurous!

  1. Limited Number of Guesses:

    • Task: Modify the game so the player only gets a fixed number of attempts (e.g., 7 guesses).
    • Details: If they guess the number within these attempts, they win as usual. If they use up all their attempts and still haven’t guessed the number, the game should inform them that they’ve lost and then reveal what the secret number was.
    • Hint:
      • You’re already using an attempts variable. You’ll need another variable, say max_attempts = 7.
      • Your while loop condition might need to change from while True: to something like while attempts < max_attempts:.
      • Inside the loop, if they guess correctly, you’ll still use break.
      • After the loop finishes, you’ll need an if statement to check why it finished. Did it finish because they guessed correctly (you might need a new boolean variable like guessed_correctly = False that you set to True upon a correct guess)? Or did it finish because attempts reached max_attempts without a correct guess? Based on this, print the win or lose message.
  2. Player Chooses the Range:

    • Task: Instead of the computer always picking a number between 1 and 100, let the player decide the range at the beginning of the game.
    • Details: Ask the player to enter a minimum number and a maximum number. The game should then use these numbers when picking the secret_number.
    • Hint:
      • You’ll need two input() calls at the start of your guess_the_number function (e.g., for min_num_str and max_num_str).
      • Remember that input() returns strings. You’ll need to convert these to integers using int().
      • It’s a very good idea to use try-except ValueError blocks around these conversions in case the user types non-numeric input for the range. You might even want a loop to keep asking until they provide valid numbers.
      • Make sure random.randint(min_num, max_num) then uses these new variables.
      • Also, update the message print("I'm thinking of a number between 1 and 100.") to reflect the new dynamic range.
  3. “Play Again?” Feature:

    • Task: After a game ends (whether the player wins or loses), ask them if they want to play again.
    • Details: If they type “yes” (or perhaps just “y”, making it case-insensitive), the entire game should start over: a new secret number should be generated, and the attempts counter should be reset to 0. If they type anything else (like “no” or “n”), the program should print a friendly “Thanks for playing!” message and then end.
    • Hint: You’ll likely need another while True: loop that wraps around almost all of your current guess_the_number function’s logic (including the generation of secret_number and the resetting of attempts). Inside this outer loop, after a game finishes, you’ll use input() to ask "Play again? (yes/no): ". If the answer isn’t “yes” (or “y”), you’ll use break to exit this outer loop.
  4. Difficulty Levels (Combines ideas from #1 and #2):

    • Task: Offer the player different difficulty levels at the start (e.g., “Easy”, “Medium”, “Hard”).
    • Details: Each difficulty level could set a different range for the secret number and a different maximum number of allowed guesses. For example:
      • Easy: Range 1-50, 10 guesses.
      • Medium: Range 1-100, 7 guesses.
      • Hard: Range 1-200, 5 guesses.
    • Hint: Ask the user for their choice of difficulty. Use if/elif/else statements to set variables like max_number_for_range and max_attempts based on their choice. Then use these variables in your game logic.

Remember, the best way to learn coding is by doing! Don’t be afraid to experiment with the code, try to make changes, and see what happens. If you get stuck, review the concepts, look at the examples, and try to break the problem down into smaller parts. Good luck, and have fun coding!