SOLVE THIS IF YOU CAN PYTHON MASTER

Joined
Jan 30, 2023
Messages
107
Reaction score
13
Here's a sample code in Python that implements a game of guessing a random number. There are two mistakes in the code and the scenario is as follows:

Python:
import random

def guess_number_game():
  secret_number = random.randint(1, 100)
  print("Guess the secret number between 1 and 100:")
  attempts = 0

  while True:
    user_guess = int(input("Enter your guess: "))
    attempts += 1
    if user_guess < secret_number:
      print("Too low. Try again.")
    elif user_guess > secret_number:
      print("Too high. Try again.")
    else:
      print(f"You got it in {attempts} attempts! The secret number was {secret_number}.")
      break
      
guess_number_game()

Scenario: Your friend is a seasoned programmer and you want to challenge them to find the two mistakes in the code. The code is a game that generates a random number and allows the user to guess what it is. The game continues until the user guesses the correct number and informs the user if their guess is too high or too low. The challenge is for your friend to find and correct the two mistakes in the code.

Mistakes:

  1. The variable attempts should be incremented before printing the too low/high message.
  2. The code does not check if the input from the user is valid, so it will raise an error if the user enters something that is not a number.
Good luck to your friend!
 
Joined
Dec 10, 2022
Messages
73
Reaction score
22
This?

Python:
import random

def guess_number_game():
  secret_number = random.randint(1, 100)
  print("Guess the secret number between 1 and 100:")
  attempts = 0

  while True:
    try:
        user_guess = int(input("Enter your guess: "))
    except ValueError:
        print('Please enter only whole numbers')
        continue
    attempts += 1
    if user_guess < secret_number:
      print(f"Attempts: {attempts}\nToo low. Try again.")
    elif user_guess > secret_number:
      print(f"Attempts: {attempts}\nToo high. Try again.")
    else:
      print(f"You got it in {attempts} attempts! The secret number was {secret_number}.")
      break
      
guess_number_game()
 
Joined
Jan 30, 2023
Messages
107
Reaction score
13
This?

Python:
import random

def guess_number_game():
  secret_number = random.randint(1, 100)
  print("Guess the secret number between 1 and 100:")
  attempts = 0

  while True:
    try:
        user_guess = int(input("Enter your guess: "))
    except ValueError:
        print('Please enter only whole numbers')
        continue
    attempts += 1
    if user_guess < secret_number:
      print(f"Attempts: {attempts}\nToo low. Try again.")
    elif user_guess > secret_number:
      print(f"Attempts: {attempts}\nToo high. Try again.")
    else:
      print(f"You got it in {attempts} attempts! The secret number was {secret_number}.")
      break
     
guess_number_game()
Sure, here's the corrected code with the mistakes fixed:


Python:
import random

def guess_number_game():
  secret_number = random.randint(1, 100)
  print("Guess the secret number between 1 and 100:")
  attempts = 0

  while True:
    try:
      user_guess = int(input("Enter your guess: "))
    except ValueError:
      print("Invalid input. Enter a number between 1 and 100.")
      continue
    if user_guess < secret_number:
      attempts += 1
      print("Too low. Try again.")
    elif user_guess > secret_number:
      attempts += 1
      print("Too high. Try again.")
    else:
      print(f"You got it in {attempts} attempts! The secret number was {secret_number}.")
      break
      
guess_number_game()

Explanation:

  • The first mistake was fixed by using a try-except block to handle the case where the user input is not a valid integer. The code now informs the user to enter a number between 1 and 100 and continues with the next iteration.
  • The second mistake was fixed by incrementing the attempts variable after the too low/high message was printed. This ensures that the number of attempts is correctly recorded.

Wait for next :)
 
Joined
Dec 10, 2022
Messages
73
Reaction score
22
In my opinion the counter worked as is. The count increased with each guess. That's why I did not change it. Why add the extra code when it's not needed.
 
Joined
Dec 10, 2022
Messages
73
Reaction score
22
Here is a version of the game I wrote some time ago. Uses tkinter. I've thought about re-writing to use dunder methods and cleaning code up a bit.

Python:
import tkinter as tk
from random import randint
 
'''
Define some global variables
start is the low number end is the high number
e.g. guess a number between 1 and 20
count is the number of tries
'''
start, end = 1, 20
count = 5
 
 
class Window:
    '''
    Define the class window. Set some variables for our game.
    Setup the layout with tkinter
    self.number is a random generated number
    self.count is the number of tries to guess the number
    '''
    def __init__(self, parent):
        self.number = self.random_number()
        self.counter = count
 
        parent.columnconfigure(0, weight=1)
        parent.rowconfigure(0, weight=1)
 
        container = tk.Frame(parent)
        container.grid(column=0, row=0, sticky='new')
        container.grid_columnconfigure(0, weight=3)
 
        header = tk.Label(parent, text='Number Guessing Game')
        header['font'] = ('times 16 bold')
        header['relief'] = 'groove'
        header.grid(column=0, row=0, sticky='new', pady=4, ipady=4)
 
        instructions = tk.Label(parent)
        instructions['text'] = f'Choose a number between {start} and {end}'
        instructions['bg'] = 'lightyellow'
        instructions['relief'] = 'groove'
        instructions.grid(column=0, row=1, sticky='new', pady=4)
 
        self.msgbox = tk.Label(parent, anchor='w')
        self.msgbox['relief'] = 'groove'
        self.msgbox['text'] = f'Tries Left: {self.counter}'
        self.msgbox.grid(column=0, row=2, sticky='new', pady=8)
 
        self.entry = tk.Entry(parent)
        self.entry.grid(column=0, row=3, sticky='new', pady=8)
 
        btn_frame = tk.Frame(parent)
        btn_frame.grid(column=0, row=4, sticky='new')
        for i in range(2):
            btn_frame.grid_columnconfigure(i, weight=3, uniform='btns')
 
        self.btn = tk.Button(btn_frame)
        self.btn['text'] = 'Submit'
        self.btn['command'] = lambda: self.check(self.entry.get())
        self.btn.grid(column=0, row=0, sticky='new')
 
        self.reset_btn = tk.Button(btn_frame)
        self.reset_btn['text'] = 'Reset'
        self.reset_btn['state'] = 'disabled'
        self.reset_btn.grid(column=1, row=0, sticky='new')
 
        msg_container = tk.Frame(parent)
        msg_container['relief'] = 'groove'
        msg_container['highlightbackground'] = 'lightgray'
        msg_container['highlightcolor'] = 'lightgray'
        msg_container['highlightthickness'] = 1
        msg_container.grid(column=0, row=5, sticky='new', pady=4)
        msg_container.grid_columnconfigure(0, weight=0)
        msg_container.grid_columnconfigure(1, weight=3)
 
        self.label = tk.Label(msg_container, text='MSG:', anchor='w')
        self.label.grid(column=0, row=0, sticky='new')
 
        self.msg_label = tk.Label(msg_container, anchor='w')
        self.msg_label.grid(column=1, row=0, sticky='new')
        self.entry.focus()
        self.entry.bind('<Return>', lambda num: self.check(self.entry.get()))
 
 
    def random_number(self):
        '''
        random_number is a function for generating a random number
        between the start and ending numbers defined above
        '''
        number = randint(start, end)
        return number
 
    def check(self, guess):
        '''
        Check does several things
        With a try statement we check to make sure only whole numbers are entered.
        If not display an error message
        '''
        try:
            guess = int(guess) # Convert gues to int
            self.counter = self.counter - 1 # Subtract 1 from the counter
            self.msgbox['text'] = f'Tries Left: {self.counter}'
 
            self.entry.delete(0, tk.END) # Clear the entry
            if guess > end or guess < start: # Check if the guess is within bounds
                if self.counter > count: # If the counter > than tries, set to default tries
                    self.counter = count
                else: # Counter is below default. Add 1 back due to incorrect input
                    self.counter = self.counter + 1
                # Display error
                self.msg_label['text'] = f'Please choose a number between {start} and {end}'
                self.msg_label['fg'] = 'red'
                self.msgbox['text'] = f'Tries Left: {self.counter}'
 
            elif guess > self.number: # Display message that the guess was too high
                self.msg_label['text'] = f'{guess} is too high.'
                self.msg_label['fg'] = 'red'
            elif guess < self.number: # Display message that guess was too low
                self.msg_label['text'] = f'{guess} is too low.'
                self.msg_label['fg'] = 'darkorange'
            else: # Display message that guess was correct
                self.msg_label['text'] = f'You win! {guess} is correct.'
                self.msg_label['fg'] = 'green'
                self.btn['state'] = 'disabled'
                self.reset_btn['state'] = 'normal'
                self.reset_btn['command'] = self.reset
 
            if self.counter == 0: # Number of tries has been reached. Disable submit button and enable reset
                self.msg_label['text'] = 'You have no tries left.'
                self.msg_label['fg'] = 'tomato'
                self.btn['state'] = 'disabled'
                self.reset_btn['state'] = 'normal'
                self.reset_btn['command'] = lambda: self.reset()
 
        except ValueError: # Display error - input is not correct
            self.msg_label['text'] = 'Error! Please enter only whole numbers.'
            self.msg_label['fg'] = 'red'
            self.entry.delete(0, tk.END)
 
 
    def reset(self):
        '''
        Resets all the default values and generates a new random number
        '''
        self.counter = count
        self.btn['state'] = 'normal'
        self.reset_btn['state'] = 'disabled'
        self.msg_label['text'] = ''
        self.msg_label['fg'] = 'black'
        self.msgbox['text'] = f'Tries Left: {count}'
        self.number = self.random_number()
 
def main():
    root = tk.Tk()
    root['padx'] = 8
    root['pady'] = 5
    root.geometry('400x210+250+250')
    root.resizable(False, False)
    Window(root)
    root.mainloop()
 
if __name__ == '__main__':
    main()
 
Joined
Dec 10, 2022
Messages
73
Reaction score
22
One more version using dunder methods for comparison

Python:
'''
    Tkinter Number Guessing Game
    Guess the random number between 1 and 100
'''
import tkinter as tk
from random import randint

class Model:
    '''
        Model class handles comparison and generate a random number
    '''
    def __init__(self, number=None):
        self.number = number

    def __lt__(self, other):
        return self.number < other.number

    def __gt__(self, other):
        return self.number > other.number

    def __eq__(self, other):
        return self.number == other.number

    def rnd_num(self):
        return randint(1, 100)

class View:
    '''
        View class handles the gui view
    '''
    def __init__(self, parent):
        # Set class variables and configure root grid
        parent.columnconfigure(0, weight=1)
        parent.rowconfigure(0, weight=1)

        # Container will hold all widgets
        container = tk.Frame(parent, relief='ridge', border=3)
        container.grid(column=0, row=0, sticky='news')
        container.grid_columnconfigure(0, weight=3)

        # Create our header widget
        header = tk.Label(container)
        header['text'] = 'Tkinter Number Guessing Game'
        header['font'] = (None, 16, 'bold')
        header['fg'] = 'blue'
        header.grid(column=0, row=0, sticky='new', padx=5, pady=3)

        # Create the direction header
        header2 = tk.Label(container, anchor='w')
        header2['text']= 'Choose a number between 1 and 100'
        header2['bg'] = 'lightyellow'
        header2.grid(column=0, row=1, sticky='new', padx=5, pady=3)

        # try_frame will hold the permanent static text as well as the variable text
        try_frame = tk.Frame(container)
        try_frame.grid(column=0, row=2, sticky='new', padx=5, pady=3)
        try_frame.grid_columnconfigure(0, weight=0)
        try_frame.grid_columnconfigure(1, weight=3)

        # Static text label
        try_text = tk.Label(try_frame, anchor='w')
        try_text['text'] = 'Tries:'
        try_text['font'] = (None, 10, 'bold')
        try_text.grid(column=0, row=0, sticky='new')

        # Variable text label
        self.try_guesses = tk.Label(try_frame, anchor='w', text='0')
        self.try_guesses['font'] = (None, 10, 'normal')
        self.try_guesses.grid(column=1, row=0, sticky='nw')

        # Entry field for entering a number
        self.entry = tk.Entry(container)
        self.entry.focus()
        self.entry.grid(column=0, row=3, sticky='new', padx=5, pady=3)

        # A Button for submitting a number
        self.button = tk.Button(container, text='Guess')
        self.button.grid(column=0, row=4, padx=5, pady=3, sticky='ne')

        # msg_frame will hold various message that will be displayed
        msg_frame = tk.Frame(container, relief='ridge')
        msg_frame['borderwidth'] = 1
        msg_frame.grid(column=0, row= 5, sticky='new', padx=8)
        msg_frame.grid_columnconfigure(0, weight=0)
        msg_frame.grid_columnconfigure(1, weight=3)

        # msg_header will hold static text
        msg_header = tk.Label(msg_frame, text='MSG:', anchor='w', padx=5)
        msg_header['font'] = (None, 10, 'bold')
        msg_header.grid(column=0, row=0, sticky='new', padx=5, pady=3)

        # self.msg is a label for displaying dynamic/changing text messages
        self.msg = tk.Label(msg_frame, anchor='w')
        self.msg['text'] = ''
        self.msg['font'] = (None, 10, 'normal')
        self.msg.grid(column=1, row=0, sticky='new', padx=5, pady=3)

class Controller:
    '''
        Controller class will handle communications between Model and View classes
    '''
    def __init__(self, view):
        '''
            Set some instant variables and get our first random number
        '''
        self.view = view
        self.rand_number = Model().rnd_num()
        self.counter = 0

        # Set out button command and also bind the Return/Enter keys as well as
        # number pad enter key to the entry field. This allows us to press them
        # as well as use the submit button
        self.view.button['command'] = lambda x=self.view.entry: self.callback(self.view.entry)
        self.view.entry.bind('<Return>', lambda x: self.callback(self.view.entry))
        self.view.entry.bind('<KP_Enter>', lambda x: self.callback(self.view.entry))

    def callback(self, arg):
        '''
            Callback function does some error checking and does the comparison
            of entered number and the random number. The try block ensures that
            only whole numbers are entered. If no errors continue to the else block
        '''
        try:
            number = int(arg.get())
        except ValueError:
            self.view.msg['text'] = 'Error! Only whole numbers are allowed.'
            self.view.msg['fg'] = 'red'
        else:
            # Set a text color for messages, increase counter, update counter text
            self.view.msg['fg'] = 'blue'
            self.counter += 1
            self.view.try_guesses['text'] = f'{self.counter}'

            # Do the comparison and return the correct message
            if Model(number=number) > Model(number=self.rand_number):
                self.view.msg['text'] = f'{number} is too high.'
            if Model(number) < Model(self.rand_number):
                self.view.msg['text'] = f'{number} is too low.'
            if Model(number) == Model(self.rand_number):
                self.view.msg['text'] = f'Congradulations! You guessed the number {self.rand_number}'
                self.view.msg['fg'] = 'green'

                # The correct number has been guessed, call this function to disable some of
                # the functions and change the button text and command to call the reset function
                self.disable()
        
        # Clear the entry field
        self.view.entry.delete(0, tk.END)

    def disable(self):
        '''
            This function disables some of the widgets and
            changes the button text and command
        '''
        self.view.entry.unbind('<Return>')
        self.view.entry.unbind('<KP_Enter>')
        self.view.entry['state'] = 'disabled'
        self.view.button['text'] = 'Reset'
        self.view.button['command'] = self.reset

    def reset(self):
        '''
         Reset function restores all counts functions and widgets
        '''
        self.counter = 0
        self.view.button['text'] = 'Guess'
        self.view.button['command'] = lambda x=self.view.entry: self.callback(self.view.entry)
        self.view.entry.bind('<Return>', lambda x: self.callback(self.view.entry))
        self.view.entry.bind('<KP_Enter>', lambda x: self.callback(self.view.entry))
        self.view.entry['state'] = 'normal'
        self.view.try_guesses['text'] = '0'
        self.view.msg['text'] = ''
        self.view.entry.delete(0, tk.END)
        self.rand_number = Model().rnd_num()


if __name__ == '__main__':
    root = tk.Tk()
    root.title('Tkinter Number Guessing Game')
    root.update()
    root.minsize(500, root.winfo_height())
    controller = Controller(View(root))
    root.mainloop()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top