Hello Everyone.
I completed a challenge from the book Python Programming for the Absolute Beginner, Third Edition on GUI development. I had to make a GUI version of a “Guess my number” game. I did it well (according to me), I will leave my code below. But I was wandering, How would a user that does not have Python installed on their PC play the game? Will I have to make it an app file or something?
#Guess my Number GUI Edition
#Import all necesarry modules (random, games and * from tkinter)
import random, games
from tkinter import *
class Adivina(Frame):
"""Guess My Number GUI Version"""
def __init__(self, master):
"""Set the attributes"""
#inherit master's attributes
super(Adivina, self).__init__(master)
self.min_num = 1 #minimum number to guess
self.max_num = 30 #maximum number to guess
self.max_attempts = 5 #maximum number of attempts
#This to do to display first GUI widgets
self.grid()
self.first_GUI_widgets()
def first_GUI_widgets(self):
"""Creates first GUI elements"""
#display instructions label
Label(self, text = "Guess a number"\
" between " + str(self.min_num) + " and " \
+ str(self.max_num)).grid(row = 0, column = 0, sticky = N, pady = 15)
#display label and input for number of trials
self.label_attempts = Label(self, text = "How many attempts would you like? "\
"(" + str(self.max_attempts) + " maximum" + ")")
self.label_attempts.grid(row = 3, column = 0, sticky = W)
self.entry_attempts = Entry(self)
self.entry_attempts.grid(row = 4, column = 0, sticky = N, pady = 10)
#display a submit button for that when it's done
self.button_attempts = Button(self, text = "Submit", command = self.attempts_number)
self.button_attempts.grid(row = 5, column = 0, sticky = S, pady = 5)
def attempts_number(self):
"""Function to work with the maximum number of attemps."""
try:
#convert what user enters to a integer
self.attempts = int(self.entry_attempts.get())
except ValueError:
#display if user enters something that is not a integer
games.error_box("Input error",
"You must enter a whole positive number.")
else:
#run if user enters a integer
if self.attempts <= 0:
#ensure the user enters a positive integer
games.warning_box("Warning",
"You must enter a whole number greater than 0.")
elif self.attempts > 5:
#ensure attempts are not greater that five
games.warning_box("Warning", "Attempts cannot be "\
"greater than 5.")
else:
#call the other_GUI_widgets method
self.other_GUI_widgets()
def other_GUI_widgets(self):
"""Other GUI widgets."""
#Define the number to guess
self.the_number = random.randint(self.min_num, self.max_num)
#Remove attempts widgets
self.label_attempts.grid_remove()
self.entry_attempts.grid_remove()
self.button_attempts.grid_remove()
#Display main game widgets
self.entry_number = Entry(self)
self.entry_number.grid(row = 4, column = 0, sticky = N, pady = 5)
#Create a submit number for the guessed number
self.button_number = Button(self, text = "Submit Guess",
command = self.game_logic)
self.button_number.grid(row = 5, column = 0, sticky = N, pady = 5)
#Create a variable for text in result label
self.label_text = ""
self.label_number = Label(self, text = self.label_text)
self.label_number.grid(row = 6, column = 0, sticky = S)
#Create a label that displays the number of attempts user has
self.show_attempts = Label(self, text = "Attempts: " + str(self.attempts))
self.show_attempts.grid(row = 1, column = 0, sticky = N)
def game_logic(self):
"""Main logic of the game"""
try:
#Declare the guessed number variable
self.guessed_number = int(self.entry_number.get())
except ValueError:
#display error if user does not enter an integer
games.error_box("Input error",
"You must enter a whole positive number.")
else:
#run if user enters a integer
#decrease the number of attempts by one
self.attempts -= 1
#display it on the label
self.show_attempts["text"] = "Attempts: " + str(self.attempts)
#what to do if we ran out of attempts
if self.attempts <= 0:
self.show_attempts["text"] = "Out of attempts!!"
#remove widgets to enter guessed number
self.entry_number.grid_remove()
self.button_number.grid_remove()
self.label_number.grid_remove()
#Tell the player about the loss
self.end_label = Label(self, text = "The number was " + str(self.the_number))
self.end_label.grid(row = 4, column = 0, sticky = N, pady = 5)
self.end_label_2 = Label(self, text = "Good luck next time")
self.end_label_2.grid(row = 5, column = 0, sticky = N, pady = 5)
#Let the player decide to wheter play again or not
self.again_button = Button(self, text = "Play Again",
command = self.all_again)
self.again_button.grid(row = 6, column = 0, sticky = N, pady = 5)
#When user guess is greater than the random number
if self.guessed_number > self.the_number:
self.label_text = "lower..."
self.label_number["text"] = self.label_text
elif self.guessed_number < self.the_number:
self.label_text = "HIGHER!!!"
self.label_number["text"] = self.label_text
elif self.guessed_number == self.the_number:
#remove widgets to enter guessed number
self.entry_number.grid_remove()
self.button_number.grid_remove()
self.label_number.grid_remove()
self.end_label = Label(self, text = "You guessed it!!")
self.end_label.grid(row = 4, column = 0, sticky = N, pady = 5)
self.end_label_2 = Label(self, text = "The number was " + str(self.the_number))
self.end_label_2.grid(row = 5, column = 0, sticky = N, pady = 5)
#Let the player decide to wheter play again or not
self.again_button = Button(self, text = "Play Again",
command = self.all_again)
self.again_button.grid(row = 6, column = 0, sticky = N, pady = 5)
def all_again(self):
"""Run when player presses the 'Play Again' button."""
self.remove_last_widgets()
self.first_GUI_widgets()
def remove_last_widgets(self):
"""Remove last widgets to restart all."""
self.end_label.grid_remove()
self.end_label_2.grid_remove()
self.again_button.grid_remove()
self.show_attempts.grid_remove()
games.make_GUI_work(Adivina,"Guess My Number GUI Edition")
The following are the games module (module I made up) functions I used:
def message_box(title, message = ""):
"""Displays an alert box."""
import tkinter
from tkinter import messagebox
box = tkinter.Tk()
box.withdraw()
messagebox.showinfo(title, message)
def make_GUI_work(class_name,title):
#Create a root window
import tkinter
root = tkinter.Tk()
root.title(title)
#instantiate the object
game = class_name(root)
#Have the GUI running in an infinite while loop until the user closes it
root.mainloop()
def error_box(title, message = ""):
"""Displays an error box."""
import tkinter
from tkinter import messagebox
box = tkinter.Tk()
box.withdraw()
messagebox.showerror(title,message)
def warning_box(title, message = ""):
"""Displays a warning message."""
import tkinter
from tkinter import messagebox
box = tkinter.Tk()
box.withdraw()
messagebox.showwarning(title, message)