Table of Contents
- Introduction
- Day 1
- Day 2
- Day 3
- Day 4
- Day 5
- 6 – Python GUI and Classes
- 7 – Change Font Size and Type
- 8 – Adding Headers to GUI
Introduction
This file is created for the 2017-2018 Colorado Early Colleges Middle School Computer Science Class. The first year it is a work in progress. For my 2017-2018 class, please share you thoughts and desires of what you would like to learn. We will make this class the best class possible.
This week is an introduction to Python. You each have Python 3.6 on your system. I have already written a brief Introduction to Python on my website, so I will just reference that here. The name is derived from the Monty Python Flying Circus television program.
Day 1
Today we will briefly introduce you to the Python environment and saving and using Python files. Please store your Python files in a Python directory on your flash/USB drive. Please start the Python Development Environment, IDLE. It has a white background and yellow and blue pythons as the logo. This will bring up the execution shell. When the execution shell is open, go to the File menu and select “New File.” A new program will open. When it does, type the following information into the window:
# Python Program 1 # # Learn Basic Python Input and Output # Find out who is playing and welcome them name = input("What is your name: ") # Ask the user for their name. print("Welcome to the game", name) # Now it is time to exit input("Press Enter to exit")
This is a very basic Python program that reads information typed on the keyboard and then displays a line including the input, followed by a second message, delaying the exit from the program. Lines starting with a ‘#’ are comment lines. Nothing following the ‘#’ will be executed. The basic information is at the top of this example. Output from this program would be:
What is your name: George Welcome to the game George Press Enter to exit
Day 2
To help the code developer do common tasks, all languages have libraries with useful functions already written. For this example, we will use a random number generator. To include a library, the import command is used. This program generates a random number and then displays it at the end of the program. Variables do not have to be declared before they are used. In this example, the variable “name” is set by user input. “answer” is generated by the random number generator, while guessCount is initialized to zero (“0”).
# Python Program 2 # # Learn how to include a library. # In this case for Random number generation library. import random # Find out who is playing and welcome them name = input("What is your name: ") print("Welcome to the game", name) # Ask the user for their name. # Let the computer generate the answer. answer = random.randint(1,1000) # Keep track how many guesses it takes guessCount = 0 # Print the Results print("the answer is:", answer, "and", name, "did it in", guessCount, "moves.") # Wait for the user to see the results. input("Press Enter to exit")
The output of the program is as follows:
What is your name: George Welcome to the game George the answer is: 995 and George did it in 0 moves. Press Enter to exit
You now have the start and the end of your program written. As we progress, it will become a bit more interesting. Eventually, you will be able to have the program generate a random number and you see how quickly you can guess it.
Day 3
If you do not want to retype the same code over and over, you need to create loops. They are usually either for loops or while loops. In this case, we will be using while loops. For loops execute over a particular set of parameters while while loops continue until a certain test value goes from True to False or a “break” command is executed.
# Python Program 3 # # Random number guessing program # Include the Random number generation library. import random # Find out who is playing and welcome them name = input("What is your name: ") print("Welcome to the game", name) # Let the computer generate the answer. maxValue = 1000 answer = random.randint(1,maxValue) print("I have chosen a number between 1 and 1,000. Try to guess it.") # Keep track how many guesses it takes guessCount = 0 #Introducing the while loop and if statement toggle = True while toggle: guessCount += 1 guess = input("What is your guess? ") guessIt = int(guess) if(guessIt == answer): print("Good Guess, you got it") break # This command will exit from the while loop immediately if(guessCount > 10): print("Too many guesses, I win") toggle = False # When toggle is checked for false, the loop will end. # Print the Results print("the answer is:", answer, "and", name, "did it in", guessCount, "moves.") # Now it is time time to exit input("Press enter to exit")
Please notice, there is only a check to see if the guess is equal to the answer. It is extremely hard to guess a number between 1 and 1,000 in a reasonable length of time. Therefore, we put on a check for the number of attempts to exit the program after 10 tries.
What is your name: George Welcome to the game George I have chosen a number between 1 and 1,000. Try to guess it. What is your guess? 500 What is your guess? 445 What is your guess? 300 What is your guess? 874 What is your guess? 993 What is your guess? 130 What is your guess? 888 What is your guess? 555 What is your guess? 777 What is your guess? 765 What is your guess? 888 Too many guesses, I win the answer is: 952 and George did it in 11 moves. Press enter to exit
Day 4
The commands if, elif, and else can be used to help your program make logical choices. elif is short for else if and is used when a decision takes multiple choices. In this case, we are adding more information to tell the user if the guesses are too high or too low.
# Python Program 4 # # Random number guessing program # Include the Random number generation library. import random # Find out who is playing and welcome them name = input("What is your name: ") print("Welcome to the game", name) # Let the computer generate the answer. maxValue = 1000 answer = random.randint(1,maxValue) print("I have chosen a number between 1 and 1,000. Try to guess it.") # Keep track how many guesses it takes guessCount = 0 #Introducing the while loop and if statement toggle = True while toggle: guessCount += 1 guess = input("What is your guess? ") guessIt = int(guess) if(guessIt == answer): print("Good Guess, you got it") toggle = False # You can use elif and else statements to give hints to the user. elif(guessIt > answer): print("Your guess is too high") else: print("Your guess is too low") # Print the Results print("the answer is:", answer, "and", name, "did it in", guessCount, "moves.") # Now it is time to exit input("Press enter to exit")
The results for one run-through are:
What is your name: George Welcome to the game George I have chosen a number between 1 and 1,000. Try to guess it. What is your guess? 555 Your guess is too low What is your guess? 777 Your guess is too low What is your guess? 888 Your guess is too low What is your guess? 950 Your guess is too low What is your guess? 988 Your guess is too low What is your guess? 995 Your guess is too high What is your guess? 993 Your guess is too high What is your guess? 991 Your guess is too high What is your guess? 989 Good Guess, you got it the answer is: 989 and George did it in 9 moves. Press enter to exit
Day 5
The main problem is when someone accidently enters a letter instead of a number. The results would be something like:
What is your name: Fred Welcome to the game Fred I have chosen a number between 1 and 1,000. Try to guess it. What is your guess? 500 Your guess is too low What is your guess? try Traceback (most recent call last): File "C:\Users\wayne.cook\Documents\2018.01\5 - Middle School\Python\python4.py", line 20, in guessIt = int(guess) ValueError: invalid literal for int() with base 10: 'try' >>>
Notice the trace-back error. When the guesser enters a letter or series of letters instead of a number, the program does not know how to handle that. We need to add what is called an exception handler to programmatically take care of this problem through a try: except: pair of commands. Remember that when a try: is around any code, an error will make the execution jump ahead to the code after the except: statement. Therefore, only have the try around the code that will need special handling if an error occurs. For example, one of my students misspelled a variable through not capitalizing one of its letters, just causing a trace-back error. Since that code was in the try: section of code, it was hidden and took a bit of time to find. The code with the try: is as follows:
# Python Program 5 # # Random number guessing program # Include the Random number generation library. import random # Find out who is playing and welcome them name = input("What is your name: ") print("Welcome to the game", name) # Let the computer generate the answer. expnt = 3 maxValue = 10**expnt answer = random.randint(1,maxValue) print("I have chosen a number between 1 and", maxValue, ". Try to guess it.") # Keep track how many guesses it takes guessCount = 0 #Introducing the while loop and if statement toggle = True while toggle: guessCount += 1 guess = input("What is your guess? ") # The input is not guaranteed to be an integer, handle exceptions # Only use the exception handler on the one line where this error # could occure. If you surround any other lines, it could mask # another error. isInteger = True try: guessIt = int(guess) except: print("Please enter an integer between 1 and", maxValue) isInteger = False if isInteger: # Only continue for an integer. # Add a test to see if the guess is within the proper range. if(guessIt < 1 or guessIt > maxValue): print("Your guess is out of the specified range") elif(guessIt == answer): print("Good Guess, you got it") toggle = False # You can use elif and else statements to give hints to the user. elif(guessIt > answer): print("Your guess is too high") else: print("Your guess is too low")# Print the Results print("the answer is:", answer, "and", name, "did it in", guessCount, "moves.") # Now it is time to exit input("Press enter to exit")
The results would be as follows. Notice how the non-integer input was handled.
What is your name: Jack Welcome to the game Jack I have chosen a number between 1 and 1000 . Try to guess it. What is your guess? 500 Your guess is too high What is your guess? Try an integer Please enter an integer between 1 and 1000 What is your guess? 200 Your guess is too high What is your guess? 100 Your guess is too low What is your guess? 150 Your guess is too high What is your guess? 120 Your guess is too high What is your guess? 110 Your guess is too high What is your guess? 106 Your guess is too high What is your guess? 103 Your guess is too low What is your guess? 104 Good Guess, you got it the answer is: 104 and Jack did it in 10 moves. Press enter to exit
Day 6
To produce more precise code, we add checks to make sure the entered amount is within the given range. The person is told when it is out of the given options for the guesses:
# Python Program 6 # # Random number guessing program # Include the Random number generation library. import random # Find out who is playing and welcome them name = input("What is your name: ") print("Welcome to the game", name) maxValue = 10**3 # Let the computer generate the answer. answer = random.randint(1,maxValue) print("I have chosen a number between 1 and", maxValue, ". Try to guess it.") # Keep track how many guesses it takes guessCount = 0 #Introducing the while loop and if statement toggle = True while toggle: guessCount += 1 guess = input("What is your guess? ") # The input is not guaranteed to be an integer, handle exceptions # Only use the exception handler on the one line where this error # could occure. If you surround any other lines, it could mask # another error. isInteger = True # Make sure this variabe has a value. try: guessIt = int(guess) except: print("Your input was not an integer, please try again.") isInteger = False # If not an integer, tell the rest of the program. if(isInteger): if(guessIt < 1 or guessIt > maxValue): print("Your guess is out of the specified range") elif(guessIt == answer): print("Good Guess, you got it") toggle = False # You can use elif and else statements to give hints to the user. elif(guessIt > answer): print("Your guess is too high") else: print("Your guess is too low") # Print the Results print("the answer is:", answer, "and", name, "did it in", guessCount, "moves.") # Now it is time to exit str = "Thank you for playing " + name + ".\nPress enter to exit" input(str)
The results are:
What is your name: Carol Welcome to the game Carol I have chosen a number between 1 and 1000 . Try to guess it. What is your guess? 500 Your guess is too high What is your guess? 4500 Your guess is out of the specified range What is your guess? try letters Your input was not an integer, please try again. What is your guess? 300 Your guess is too high What is your guess? 100 Your guess is too high What is your guess? 50 Your guess is too low What is your guess? 75 Your guess is too high What is your guess? 66 Your guess is too high What is your guess? 57 Your guess is too high What is your guess? 53 Your guess is too high What is your guess? 52 Good Guess, you got it the answer is: 52 and Carol did it in 11 moves. Thank you for playing Carol. Press enter to exit
Module Tests
There are two tests for this unit. The first is a written test with answers needed to some basic questions about Python. The second test is a modification of your current code, only using elements that you have already used. The first test will be handed to you in class and you will have one class period to finish it. The second test requirements are:
Quiz 2 – Python
Random number guessing program
QUIZ ASSIGNMENT
HINT: An example of everything you need to solve this problem is in this file.
- Ask the user to enter the exponent value of the exponent for the power of 10 of the guess (a number between 1 and 8 that represents the number of zeroes after the 1 for the maximum value).
- Check for the number being out of this range and tell the user.
- Be sure to loop until a proper value is entered.<li?
- Enclose the typed code in an exception handler (try/except pair) and tell the user if an non-integer is entered.
- If all checks pass, run a test with the exponent set to 8(max number = 1*108 with 8 zeroes after the 1.
- Questions: How long did this take?
- Submit your zipped (compressed) code file.
Python GUI and Classes
This section is to be expanded. But I will give you the final code now:
# application.py # <Your Name> # This file sets up a simple user interface to surround your number guessing # game. This file contains the definition of the interface. It uses a # "Class" definition, which can be instantiated from your main program. # Created: 23 April 2018 - WWC - Set up basic program # Modified: <Date> - <your Initials> - <what you did> # # Import the tkinter library, which is the user interface, and set up # the root to which the frame is added. from tkinter import * import random # Set up Number Guessing Game. Make a class for all of the widgets. # It is based on the Python Frame class. class Application(Frame): """ GUI application which wraps around your number guessing game. """ # Define how to initialize this class def __init__(self, master): """ Initialize the frame. """ super(Application, self).__init__(master) self.grid() self.create_widgets() self.maxValue = 1000 self.answer = random.randint(1,self.maxValue) self.guesses = 0 # Define each of the widgets you use. def create_widgets(self): """ Create button, text, and entry widgets. """ # create instruction label self.inst_lbl = Label(self, text = "A random number is generated: 1-1000, please guess!") self.inst_lbl.grid(row = 0, column = 0, columnspan = 2, sticky = W) # create label for Number Guess self.num_lbl = Label(self, text = "Number Guess: ") self.num_lbl.grid(row = 1, column = 0, sticky = W) # create entry widget to accept password self.num_ent = Entry(self) self.num_ent.grid(row = 1, column = 1, sticky = W) # create submit button self.submit_bttn = Button(self, text = "Submit: 0", command = self.coompare) self.submit_bttn.grid(row = 2, column = 0, sticky = W) # create text widget to display message self.guess_txt = Text(self, width = 35, height = 5, wrap = WORD) self.guess_txt.grid(row = 3, column = 0, columnspan = 2, sticky = W) def coompare(self): """ Display message based on your guess. """ self.guesses += 1 self.submit_bttn["text"] = "Submit: " + str(self.guesses) contents = int(self.num_ent.get()) if contents == self.answer: message = "SPOT-ON. You took " + str(self.guesses) + " moves" self.answer = random.randint(1,self.maxValue) self.guesses = 0 elif int(contents) < self.answer: message = "Your answer is too low." else: message = "Your answer is too high." self.guess_txt.delete(0.0, END) self.guess_txt.insert(0.0, message) # main def main(): root = Tk() root.title("Number Guessing Game") root.geometry("300x150") app = Application(root) root.mainloop() # Start the program: main()
7 - Change Font Size and Type
To make the text larger for any label, text, or button, you must add a font descriptor to your definition. This can be done by adding:
, font=("Times", 16) # to make the font Times and the font size 16. --or-- , font=("Times", 16, "italic") # to also make the font italic.
to your labels, buttons, texts, or other GUI definitions. Your assignment is to make all of your fonts "times" and 16pt. The second line adds italic to the description. A typical line would look like:
self.inst_lbl = Label(self, text = "A random number is generated: 1-1000 please guess!", font=("Times", 16))
One other line that needs to be changed in order to have enough room in your program is:
root.geometry("500x250")
Make the changes for all labels, texts, and buttons.
8 - GUI and Class Quiz
Please type these questions and the answers to these questions in a Word document. Turn into IC Python Class and GUI Quiz (QPCG).
- Explain what a class in programming is and how to use it.
- What is the purpose of "self" at the beginning of references to all functions and variables.
- Why do some references have parentheses and some do not?.
- Why would you use a class to group common functions?.
9 - Adding Headers to GUI
Menus can be added to any Python GUI interface. First, the proper library must be included. In order to have popups for your commands, you need to import the following item, put this statement immediately after the line in bold/italics.
from tkinter import * from tkinter.messagebox import showinfo
Each button has to have a call to a handling methods, routine, or function. I have added the "def" methods to my application class. Note that the menu items have to call a method with no parameters. In this case, I just have each of these methods call a common method with a parameter. The methods are:
# Menu routines def SetMax(self, maxValueIn): self.maxValue = maxValueIn self.inst_lbl.config(text = "A random number is generated: 1-" + str(self.maxValue) + ", please guess!") self.answer = random.randint(1,self.maxValue) self.guess_txt.delete(0.0, END) self.guess_txt.insert(0.0, "max value set to " + str(self.maxValue)) def SetMax10(self): self.SetMax(10) def SetMax100(self): self.SetMax(100) def SetMax1000(self): self.SetMax(1000) def SetMax10000(self): self.SetMax(10000) def SetMax100000(self): self.SetMax(100000) def SetMax1000000(self): self.SetMax(1000000)
Notice the indent, it is so that it aligns with the other method definitions in the application class. The following functions must be added to handle the menu calls. They are first level, not part of the Application class, functions.
def hello(): showinfo("Proper Instructions will go here!") def help(): showinfo("What type of help would you like to provide?")
The menu definitions follow. The place to insert them is indicated by italicized commands.
app = Application(root) #app.CreateMenu(root) menubar = Menu(root) # create a pulldown menu, and add it to the menu bar filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Open", command=hello) filemenu.add_command(label="Save", command=hello) filemenu.add_separator() filemenu.add_command(label="Exit", command=root.quit) menubar.add_cascade(label="File", menu=filemenu) # create more pulldown menus maxmenu = Menu(menubar, tearoff=0) maxmenu.add_command(label="10", command=app.SetMax10) maxmenu.add_command(label="100", command=app.SetMax100) maxmenu.add_command(label="1000", command=app.SetMax1000) maxmenu.add_command(label="10,000", command=app.SetMax10000) maxmenu.add_command(label="100,000", command=app.SetMax100000) maxmenu.add_command(label="1,000,000", command=app.SetMax1000000) menubar.add_cascade(label="MaxMenu", menu=maxmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", command=help) menubar.add_cascade(label="Help", menu=helpmenu) # Now set the original range app.SetMax(1000) # display the menu root.config(menu=menubar) root.mainloop()