Part 1 – Python

Table of Contents

Introduction

WW Cook portraitThis 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.

  1. 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).
  2. Check for the number being out of this range and tell the user.
  3. Be sure to loop until a proper value is entered.<li?
  4. Enclose the typed code in an exception handler (try/except pair) and tell the user if an non-integer is entered.
  5. If all checks pass, run a test with the exponent set to 8(max number = 1*108 with 8 zeroes after the 1.
  6. Questions: How long did this take?
  7. 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).

  1. Explain what a class in programming is and how to use it.
  2. What is the purpose of "self" at the beginning of references to all functions and variables.
  3. Why do some references have parentheses and some do not?.
  4. 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()