IT 117: Intermediate Scripting
Class 25
Review
New Material
Microphone
Graded Quiz
You can connect to Gradescope to take weekly graded quiz
today during the last 15 minutes of the class.
Once you start the quiz you have 15 minutes to finish it.
You can only take this quiz today.
There is not makeup for the weekly quiz because Gradescope does not permit it.
Final Exam
The final exam will be held on Thursday, December 19th from
3 to 6 PM.
The exam will be given in this room.
If for some reason you are not able to take the Final at the time it will
be offered, you MUST send an email to me before the exam
so we can make alternative arrangements.
The final will consist of questions taken from the Graded Quizzes, along
with questions asking you to write short segments of Python code.
60% of the points on this exam will consist of questions from the Graded
Quizzes.
You do not need to study a Graded Quiz question if the topic is not
mentioned in either the Midterm or Final review.
The remaining 40% will come from 4 questions that ask you to write
some code.
To study for the code questions you should know
- How to write a regular expression
- How to use the os and
sys modules
- How to write a class definition
- How to write a recursive function
A good way to study for the code questions is to review the Class Exercises,
homework solutions and Class Notes.
The last class on Thursday, December 1oth, will be a review session.
You will only be responsible for the material in that review session,
which you will find here,
and the review for the Midterm, which you will find
here.
Although the time alloted for the exam is 3 hours, I would
expect that most of you would not need that much time.
The final is a closed book exam.
To prevent cheating, certain
rules
will be enforced during the exam.
Readings
If you have the textbook read Chapter 13,
GUI Programming.
Questions
Are there any questions before I begin?
Review
Recursive Functions
- The body of a function consists of statements
- A function call is a statement
- So a function can call itself
- A function that calls itself is a
recursive function
Writing Recursive Functions
Calculating the Factorial of a Number
- To make sure that recursion comes to an end
- You must have two things
- A base case: code that that makes the recursion stop
- The recursive call must approach the
base case
- We can illustrate this with a function to calculate factorials
- The factorial of n is written as
n!
- It is defined as product of multiplying all numbers from 1 ...
- up to n
- The formula for factorial is
n! = (n-1)! * n
- Note that this definition is, itself, recursive
- The factorial of 1 has a different value
1! = 1
- This is the base case
- Here is a recursive function to calculate the factorial
def factorial(num):
if num == 1:
return 1
else:
return factorial(num -1) * num
- Calling this function I get
>>> print("5!:",factorial(5))
5!: 120
Calculating Fibonacci Numbers
- The Fibonacci numbers are a sequence of integers
- The first two numbers are
1 1
- The next number is the sum of the preceding two numbers
- Here are the first ten Fibonacci numbers
1 1 2 3 5 8 13 21 34 55
- Here's the formula for the nth Fiboacci number in the sequence
F(n) = F(n - 1) + F(n - 2)
- But this definition only works if we further specify
F(1) = 1
F(2) = 1
- They are the base cases
- Here is a recursive function to calculate the nth Fibonacci number
def fibonacci(num):
if num == 1 or num == 2:
return 1
else:
return fibonacci(num - 1) + fibonacci(num - 2)
- To get the Fibonacci sequence ...
- I have to call this function inside a
for
loop
for n in range(1, 11):
print(fibonacci(n), end=" ")
- I get
1 1 2 3 5 8 13 21 34 55
Another Example of Recursion
- The
hierarchical filesystem
is recursive
- The special directory at the top called
root
contains directories
- Each of which in turn contains other directories
- And so on
- Let's write a program to count the number of directories
- Here is the algorithm
set a counter to 0
get a list of all the entries in the current directory
for each entry
if the entry is a directory
increase the count by 1
run the function on this new directory
and increase the count by what it returns
return the count
- Here is the code
def dir_count(path):
count = 0
entries = os.listdir(path)
for entry in entries:
entry_path = path + "/" + entry
if os.path.isdir(entry_path):
count += 1
count += dir_count(entry_path)
return count
Replacing Recursion with a Loop
- Anything that can be done with recursion ...
- can also be done with a loop
- Recursive functions take more memory than loops
- Each time you make a recursive call ...
- the interpreter sets aside a bit of memory ...
- which is only released when the function ends
- So why use recursion at all?
- Because it can save time when writing code
- It is often easier to create a recursive algorithm ...
- than one that uses a loop
- Memory is relatively cheap
- And good programmers are expensive
- So it's often best to go with recursion
Calculating Factorials with a Loop
- We can calculate factorials with a loop
set a factorial variable to 1
set a count variable to 1
while count is less than the number whose factorial we are computing
increment count
set factorial to count times the current value of factorial
return the factorial value
- Turning this into Python code we get
def factorial(number):
value = 1
count = 1
while count < number:
count += 1
value *= count
return value
Calculating Fibonacci Numbers with a Loop
- We can also calculate a Fibonacci number with a loop
- Here is the algorithm
if the number is 1
return 1
else:
set the first number variable to 0
set the second number variable to 1
set count to 1
while count is less than the number
increment count by 1
set value to first number plus the second number
set first to second
set second to value
return value
- Turning this into code, we get
def fibonacci(number):
if number == 1:
return 1
else:
first = 0
second = 1
count = 1
while count < number:
count += 1
value = first + second
first = second
second = value
return value
- Compare this to the code for the recursive version
def fibonacci(num):
if num == 1 or num == 2:
return 1
else:
return fibonacci(num - 1) + fibonacci(num - 2)
Direct versus Indirect Recursion
- Recursion
is where something refers to itself
- The functions above refer to themselves directly
- This is called
direct recursion
- But you can also have
indirect recursion
- In indirect recursion a function defines itself in term of another function
- And that function defines itself using the original function
- So if function A calls function
B
- And function B calls function
A
- This would be an example of indirect recursion
- The can be any number of functions involved in indirect recursion
- So function A can call function
B
- Which calls function C
- Which calls function D
- Which calls function A
Attendance
New Material
The First Computer Interfaces
- The input to the first computers used punch cards
- The statements for each line of the code were typed onto a card ...
- which were punched by a special machine
- That machine had a keyboard and a hopper for a stack of cards
- If you made a typing mistake ...
- you ripped out the card and started over
- Your program consisted of a deck of cards
- Which were fed into a card reader to run the program
- You wrapped a rubber band around the deck ...
- to keep the cards in their proper order
- If you didn't and you tripped and fell ...
- you would have to reorder all your cards
- The data was also on punch cards
- The output of the program was a paper printout
- You took this back to your office to evaluate the results
- If you found an error in the code or output ...
- you had to puzzle through the print out to find the problem
- Then you wrote new code on a piece of paper
- Punched more cards
- And tried again
The Command Line as an Interface
- Then came video terminals
- They were a combination of a television tube and a keyboard
- By this time there were multiuser operating systems
- So many terminals could be connected to the same machine
- The video monitors used the same technology as television sets
- But they did not display images
- Computers then only produced text ...
- not graphics
- The only interface available was the command line
- The command line is not a user friendly environment
- You have to remember the names of each command
- And a misspelled command caused an error
Birth of the Graphical User Interface
- The command line interface was OK for technical people
- But most people found it very hard to use
- Then along came an engineer named Douglas Engelbart
- While working at SRI in the 60's he invented a number of things ...
- that we now take for granted
- The mouse
- Windows
- Icons
- Menu bars
- Engelbart demonstrated these in a famous presentation ...
- that is now known as
"The Mother of All Demos"
- This was the birth of the
Graphical User Interface
- Usually referred to a
GUI
- In a GUI you click on icons
- Much as you would pick up a physical object
- You do not have to type commands
- Instead you selected options from a menu
- And you talk to the program using dialog boxes
- The first commercially succesful implementation of a GUI ...
- was the Macintosh, introduced in 1984
GUI Programs Are Event-Driven
- How does a computer know when to do something for you?
- When you run a program on the command line the answer is simple
- Once you start the program ...
- it gives you choices ...
- and then acts accordingly
- So the program determines the order in which things happen
- This is not what happens each time you use your laptop
- You can do many things
- Open a window
- Run a command from a menu
- Resize a window
- Run a program
- And many other possibilities
- In other words, you decide what to do ...
- and in what order
- All this is made possible by the graphics software that
comes with the operating system
- And how do you do make these thing happen?
- By
- Double click on something
- Click a button
- Click and drag on a Menu
- Click a close box
- Click and drag window edges
- The reason this happens is that any time you
- Move the mouse
- Click on something
- Enter some text
- The graphics system of your machine creates something called an
event
- The operating system sends each of these events to the program
- The program then decides how to respond
- This is call
event-driven programming
Running Graphic Programs
- Graphic programs need help
- They can't do it all themselves
- They need to run inside windows
- They need something that will swing into action ...
- when we click something
- In short they need a graphical infrastructure
- Code that will give us the graphical interface ...
- that we have come to expect
- The programs should not have to provide this code themselves
- They need it to be provided by the underlying operating system
- A Linux machine can be configured to provide this graphical code
- But the graphics code needs lots of CPU time ...
- to work properly
- If a Linux box is configured just to run services ...
- like a web server ...
- there is no need to install the graphics code
- All you need for these machines is the command line
- pe15 does not have the code that supports graphics
- So you can't run these programs on pe15
- But you can run them on your machines ...
- using IDLE
- I can also start these programs on the command line on my Mac
- Because my Mac has the graphic code needed to run these programs
The Tkinter Module
- Python can talk to the operating system using the
os module
- But the functions in os are limited
- They only handle things you can do on the command line
- You need totally different functions for GUI programming
- The command line is a very simple interface
- And does not require much code to implement
- A GUI environment is more complicated ...
- and has hundreds of lines of code
- The GUI is provided by the operation system
- Each language needs special functions to talk to the GUI
- There are a number of Python modules that have such functions
- But we will be using Tkinter
- Tkinter is not the only GUI toolkit for Python
- But it is the one most commonly used
Using Tkinter
Changing the Empty Window
- The empty window does not look like much
- But it can do anything an ordinary window can do
- You can resize it
Running Graphical Python Programs
- Graphic programs run inside a GUI environment
- Which must be provided by the operating system
- Tkinter does not create the windows itself
- It asks the GUI environment to do it
- This means the windows on different operating systems look different
- It also means that you cannot run graphical Python programs
on pe15 ...
- or any of the CS Unix machines
- They do not have the code to provide a GUI environment
- When we write graphical programs we use
widgets
- A widget is a control element such as a button or a scroll bar
- All these widgets are classes in Tkinter
- We can create multiple widget objects using Tkinter
- But they have to be attached to something
- Often that something is the root window
- But widgets can be attached to other widgets
- This forms a widget hierarchy ...
- with the root window at the top of this hierarchy
- Here is a list of the most import widget classes
Widget |
Description |
Button |
A button that can cause an action to occur when it is clicked |
Canvas |
A rectangular area that can be used to display graphics |
Checkbutton |
A button that may be in either the "on" or "off" position |
Entry |
An area in which the user may type a single line of input from the keyboard |
Frame |
A container that can hold other widgets |
Label |
An area that displays one line of text or an image |
Listbox |
A list from which the user may select an item |
Menu |
A list of menu choices that are displayed when the user
clicks a Menu widget
|
Menubutton |
The part of a drop-down menu that stays on the screen all the time |
Message |
Displays multiple lines of text |
Radiobutton |
A widget that can be either selected or deselected.
Radiobutton widgets usually appear in groups
and allow the user to select one of several options
|
Scale |
A widget that allows the user to select a value by moving a slider along a track |
Scrollbar |
Can be used with some other types of widgets to provide scrolling ability |
Text |
A widget that allows the user to enter multiple lines of text input |
Toplevel |
A container, like a Frame,
but displayed in its own window |
- A Label widget displays text or an image inside a
window
- Labels, like all widgets, are objects
- They are created using the Label constructor
- The constructor needs to know the object where the widget is attached
- This object is often the root window
- The Label constructor sets the text of the label
- Using the
named argument
text
- A named argument is when a value is given to a function call ...
- but not in its correct position in the parameter list
- This is done by writing the name of the parameter ...
- followed by an = sign ...
- followed by the value
- Like this
print(1,2,3,4,5, sep=",")
- Here is a script to create a window with a label
import tkinter
class HelloWindow:
def __init__(self):
self.main_window = tkinter.Tk()
self.main_window.title("Hello")
self.main_window.geometry("400x200")
self.label = tkinter.Label(self.main_window, text="Hello, world!")
self.label.pack()
tkinter.mainloop()
root = HelloWindow()
- The line in green creates the object
- But is won't appear until you run the pack method
- The line that does this appears in blue
- I'll talk more about the pack method in another class
- When we run the script, we get
Changing the Fonts in a Label
Changing the Way I Import Tkinter
- Up to this point, I have imported Tkinter like this
import tkinter
- This means that I always have to use
dot notation
when calling a method
self.main_window = tkinter.Tk()
...
self.label = tkinter.Label(self.main_window, text="Hello, world!", font="times 24 bold")
...
tkinter.mainloop()
- If you are only using a few methods, this is not a problem
- But graphic programs usually make frequent method calls
- There is a way to eliminate the need for dot notation
- From now on, I will always import Tkinter like this
from tkinter import *
- After I do this, code I wrote above will now be written
self.main_window = Tk()
...
self.label = Label(self.main_window, text="Hello, world!", \
font="times 24 bold")
...
mainloop()
Changing Label Colors
- The label color is set using the fg named argument
- fg stands for "foreground"
- To change the color of the label to blue ...
- I make the following changes to the call to the constructor
self.label = Label(self.main_window, text="Hello, world!", \
font="times 24 bold", fg="blue")
- When I run the script I now get
- There are a number of colors that have names in Tkinter
from tkinter import *
class ColorWindow:
def __init__(self):
self.main_window = Tk()
self.main_window.title("Colors")
self.main_window.geometry("400x200")
self.red_label = Label(self.main_window, text="Red text", fg="red")
self.red_label.pack()
self.orange_label = Label(self.main_window, text="Orange text", fg="orange")
self.orange_label.pack()
self.yellow_label = Label(self.main_window, text="Yellow text", fg="yellow")
self.yellow_label.pack()
self.green_label = Label(self.main_window, text="Green text", fg="green")
self.green_label.pack()
self.blue_label = Label(self.main_window, text="Blue text", fg="blue")
self.green_label.pack()
self.violet_label = Label(self.main_window, text="Violet text", fg="violet")
self.violet_label.pack()
self.cyan_label = Label(self.main_window, text="Cyan text", fg="cyan")
self.cyan_label.pack()
self.magenta_label = Label(self.main_window, text="Magenta text", fg="magenta")
self.magenta_label.pack()
self.brown_label = Label(self.main_window, text="Brown text", fg="brown")
self.brown_label.pack()
mainloop()
root = ColorWindow()
- When run, it looks like this
- For a complete list of named colors in Tkinter go
here
- Colors can also be specified by RGB (red green blue) values
Privacy
Class Exercise
Class Quiz