Advance Python Programming
Advance Python Programming
Advance Python Programming
ut
ib
tr
is
D
STUDENT MANUAL
or
Python®
e
at
Programming:
lic
Advanced
up
D
ot
N
o
D
e
ut
Python®
ib
tr
Programming:
is
D
Advanced
or
e
at
lic
up
D
ot
N
o
D
Python® Programming: Advanced
e
Part Number: 094012
ut
Course Edition: 1.0
Acknowledgements
ib
PROJECT TEAM
tr
Author Media Designer Content Editor
is
Richard K. Blum Brian Sullivan Michelle Farney
D
Notices
DISCLAIMER
or
While Logical Operations, Inc. takes care to ensure the accuracy and quality of these materials, we cannot guarantee their
accuracy, and all materials are provided without any warranty whatsoever, including, but not limited to, the implied warranties of
merchantability or fitness for a particular purpose. The name used in the data files for this course is that of a fictitious company. Any
resemblance to current or future companies is purely coincidental. We do not believe we have used anyone's name in creating this
e
course, but if we have, please notify us and we will change the name in the next revision of the course. Logical Operations is an
independent provider of integrated training solutions for individuals, businesses, educational institutions, and government agencies.
at
The use of screenshots, photographs of another entity's products, or another entity's product name or service in this book is for
editorial purposes only. No such use should be construed to imply sponsorship or endorsement of the book by nor any affiliation of
such entity with Logical Operations. This courseware may contain links to sites on the Internet that are owned and operated by third
lic
parties (the "External Sites"). Logical Operations is not responsible for the availability of, or the content located on or through, any
External Site. Please contact Logical Operations if you have any concerns regarding such links or External Sites.
up
TRADEMARK NOTICES
Logical Operations and the Logical Operations logo are trademarks of Logical Operations, Inc. and its affiliates.
®
Python is a registered trademark of the Python Software Foundation (PSF) in the U.S. and other countries. All other product and
service names used may be common law or registered trademarks of their respective proprietors.
D
Copyright © 2017 Logical Operations, Inc. All rights reserved. Screenshots used for illustrative purposes are the property of the
software proprietor. This publication, or any part thereof, may not be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording, storage in an information retrieval system, or otherwise, without
ot
express written permission of Logical Operations, 3535 Winton Place, Rochester, NY 14623, 1-800-456-4677 in the United States
and Canada, 1-585-350-7000 in all other countries. Logical Operations’ World Wide Web site is located at
www.logicaloperations.com.
N
This book conveys no rights in the software or other products about which it was written; all use or licensing of such software or
other products is the responsibility of the user according to terms and conditions of the owner. Do not make illegal copies of books
or software. If you believe that this book, related materials, or any other Logical Operations materials are being reproduced or
transmitted without permission, please call 1-800-456-4677 in the United States and Canada, 1-585-350-7000 in all other countries.
o
D
Python® Programming:
Advanced
e
ut
ib
tr
is
Lesson 1: Using Object-Oriented Python.........................1
D
Topic A: Create and Use Classes in an Application..........................2
Topic B: Use Magic Methods......................................................... 15
or
Topic C: Incorporate Class Factories............................................. 25
e
Lesson 2: Creating a GUI...............................................33
at
e
Lesson 6: Implementing Unit Testing.................................. 125
ut
Topic A: Test-Driven Development....................................................... 126
ib
Topic B: Write and Run a Unit Test Case............................................... 130
Topic C: Create a Test Suite..................................................................136
tr
is
Lesson 7: Packaging an Application for Distribution........... 143
D
Topic A: Create a Package Structure..................................................... 144
Topic B: Generate the Package Distribution Files.................................. 151
or
Topic C: Generate a Windows Executable..............................................156
Solutions............................................................................................ 165
e
Glossary............................................................................................. 169
at
Index.................................................................................................. 173
lic
up
D
ot
N
o
D
About This Course
e
ut
ib
Python® continues to be a popular programming language, perhaps owing to its ability to
get a lot of work done in few lines of code, and its versatility. Python is useful for
tr
developing custom software tools, applications, web services, and cloud applications. In this
course, you'll build upon your basic Python skills, learning more advanced topics such as
is
object-oriented programming patterns, development of graphical user interfaces, data
management, threading, unit testing, and creating and installing packages and executable
D
applications.
Course Description
Target Student or
This course is designed for existing Python programmers who have at least one year of
e
Python experience and who want to expand their Python proficiencies.
at
Course Prerequisites
To ensure your success in this course, you should have experience with object-oriented
lic
programming and Python 2.x or 3.x. You can obtain this level of skill and knowledge by
taking the following Logical Operations course:
• Python® Programming: Introduction
up
Course Objectives
In this course, you will expand your Python proficiencies.
D
You will:
• Create object-oriented Python applications.
• Design and create a GUI.
ot
Logon and access information for your CHOICE environment will be provided with your
class experience. The CHOICE platform is your entry point to the CHOICE learning
experience, of which this course manual is only one part.
| Python® Programming: Advanced |
On the CHOICE Home screen, you can access the CHOICE Course screens for your specific
courses. Visit the CHOICE Course screen both during and after class to make use of the world of
support and instructional resources that make up the CHOICE experience.
Each CHOICE Course screen will give you access to the following resources:
• Classroom: A link to your training provider's classroom environment.
• eBook: An interactive electronic version of the printed book for your course.
• Files: Any course files available to download.
• Checklists: Step-by-step procedures and general guidelines you can use as a reference during
e
and after class.
ut
• Spotlights: Brief animated videos that enhance and extend the classroom learning experience.
• Assessment: A course assessment for your self-assessment of the course content.
• Social media resources that enable you to collaborate with others in the learning community
ib
using professional communications sites such as LinkedIn or microblogging tools such as
Twitter.
tr
Depending on the nature of your course and the components chosen by your learning provider, the
CHOICE Course screen may also include access to elements such as:
is
• LogicalLABS, a virtual technical environment for your course.
• Various partner resources related to the courseware.
D
• Related certifications or credentials.
• A link to your training provider's website.
• Notices from the CHOICE administrator.
• Mentoring services. or
• Newsletters and other communications from your learning provider.
Visit your CHOICE Home screen often to connect, communicate, and extend your learning
e
experience!
at
As You Learn
This book is divided into lessons and topics, covering a subject or a set of related subjects. In most
cases, lessons are arranged in order of increasing proficiency.
up
The results-oriented topics include relevant and supporting information you need to master the
content. Each topic has various types of activities designed to enable you to solidify your
understanding of the informational material presented in the course. Information is provided for
D
course files may contain media components to enhance your learning and additional reference
materials for use both during and after the course.
N
Checklists of procedures and guidelines can be used during class and as after-class references when
you're back on the job and need to refresh your understanding.
At the back of the book, you will find a glossary of the definitions of the terms and concepts used
o
throughout the course. You will also find an index to assist in locating information within the
instructional components of the book.
D
As You Review
Any method of instruction is only as effective as the time and effort you, the student, are willing to
invest in it. In addition, some of the information that you learn in class may not be important to you
immediately, but it may become important later. For this reason, we encourage you to spend some
time reviewing the content of the course after your time in the classroom.
As a Reference
The organization and layout of this book make it an easy-to-use resource for future reference.
Taking advantage of the glossary, index, and table of contents, you can use this book as a first
source of definitions, background information, and summaries.
Course Icons
Watch throughout the material for the following visual cues.
e
Icon Description
ut
A Note provides additional information, guidance, or hints about a topic or task.
A Caution note makes you aware of places where you need to be particularly careful
ib
with your actions, settings, or decisions so that you can be sure to get the desired
results of an activity or task.
tr
Spotlight notes show you where an associated Spotlight is particularly relevant to
the content. Access Spotlights from your CHOICE Course screen.
is
Checklists provide job aids you can use after class as a reference to perform skills
back on the job. Access checklists from your CHOICE Course screen.
D
Social notes remind you to check your CHOICE Course screen for opportunities to
interact with the CHOICE community using social media.
or
e
at
lic
up
D
ot
N
o
D
e
ut
Lesson Time: 3 hours, 45 minutes
ib
tr
is
Lesson Objectives
D
In this lesson, you will:
Lesson Introduction
lic
your applications. Python provides support for most standard object-oriented programming
features to enable you to build complete object-oriented applications.
D
ot
N
o
D
2 | Python® Programming: Advanced
TOPIC A
Create and Use Classes in an Application
Object-oriented programming enables you to organize and reuse common features in applications.
In this topic, you’ll create and use classes.
e
You may want show the
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
ut
from the CHOICE course screen.
Course screen or have
students navigate out to
ib
the Course screen and Classes
watch them as a
supplement to your With object-oriented programming, everything is related to classes. Classes are the data and functions
tr
instruction. If not, please you use in your applications, grouped together into a single entity. For example, if you’re writing a
remind students to visit program that uses cars, you can create a car class that contains information on the car’s make,
the Spotlights for this
is
model, price, and how many doors it has. If you’re writing an application that tracks people, you
course on their CHOICE
Course screen after might create a person class that contains information on each person’s name, age, height, weight,
and gender. An object-oriented programming class defines an object using members. There are two
D
class for supplemental
information and basic types of class members:
additional resources. • Attributes—denote features of an object (such as the weight, engine, and number of doors of a
Classes
or
car). A class can contain many attributes, each describing a different feature of the car.
• Methods—similar to Python functions, perform an operation using the attributes of the class. A
class method should be contained within the class and only use the attributes from that class.
You define the attributes and methods inside a class definition. The class definition uses the class
e
keyword, along with the class name. While not required, it's become somewhat standard in Python
at
for class names to begin with an uppercase letter. Follow the class name with a colon to indicate
more code is required to define the class:
lic
After defining the class, you can use it anywhere in your program to denote that object. Each use of
the class is called an instance. Each class instance is assigned to a variable in the program:
>>> car1 = Car()
>>>
D
Attributes
Attributes Attributes are variables that hold data that applies to the class. There are two types of attributes you
N
Methods
Classes consist of more than just a bunch of attributes. You also need to bundle functions for Methods
e
handling the attributes. In object-oriented programming, functions are called methods. Just like with
attributes, there are two types of methods that you can define in Python:
ut
• Class methods
• Instance methods
ib
Class Methods
tr
Class methods are functions that are independent of any instance data. To define a class method, Class Methods
you must first add an @classmethod decorator line before the method definition. You then define
is
the method much like a function, including the def keyword:
>>>class Car:
D
... @classmethod
... def calcMPG(cls, miles, gallons):
... return miles / gallons
...
or
The class method uses parameters to pass data into the method, and the return statement to pass a
single value back to the main program. The first parameter must be the cls keyword. This tells
e
Python to reference the class instead of an instance of the class.
at
The calcMPG class method uses the variables passed to it in the arguments, and returns the output
back to the main program
lic
Instance Methods
Instance methods work on attributes defined for the instance. Instance methods must always use at Instance Methods
up
least one parameter, called self. The self parameter points to the instance that's using the method.
When you use the instance method, you don't include the self parameter, Python assumes it by
default.
D
To define an instance method again, you use the def keyword, just like when defining functions:
>>>class Car:
... def __init__(self, make, model, price, inventory):
ot
self.model,
D
self.price,
self.inventory))
...
The __init__ instance method is a special method that defines the initial values for the instance
attributes. This will be discussed more later. The display method is an instance method created to
display the instance values instead of having to use the print statement all the time when you want
to see the attribute values.
Inside the instance method definitions, the self keyword is used to reference the attribute values
for the instance. The __init__ method uses that to apply the parameter values to the instance
attributes. The display method also uses that in the self keyword to reference the values of the
attributes for the current instance.
e
Define a Class
ut
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
CHOICE Course screen.
ib
Students can enter the You create a complete class definition by putting together the class definition, attributes, and
example code using the methods into one code block.
Command Prompt
tr
feature in PyCharm to Define a Class
see the results as you
Define a new class by using the class keyword, along with the class name and a colon. The class
is
go through the sections.
name you choose must be unique within your program. Although it’s not required, it’s somewhat of
a de facto standard in Python to start class names with an uppercase letter:
D
>>> class Car:
...
... axles = 2
...
lic
functions that can be used with the object. Remember to use the @classmethod decorator before
defining the class method, and use the cls keyword as the first parameter:
... @classmethod
... def calcMPG(cls, miles, gallons):
D
Note: Be careful when defining methods in a class definition. Make sure that the method code
block is indented farther than the method definition statement.
N
Define an Instance
Method Define an Instance Method
Define instance methods that support the class object. Use the __init__ method to create a class
o
constructor to define any instance variables for the class. Then create additional instance methods to
support functions required to interact with the class objects:
D
Create an Instance
Create an Instance
The class definition creates the class template, but doesn’t put the class to use. To use a class, you
have to instantiate it. When you instantiate a class, you create an instance of the class in your
program. Each instance represents one occurrence of the object. Each instance is a separate object
e
in Python. If you create a second instance of the Car class, the attributes you define are separate
from the attributes you define in the first instance:
ut
>>> car1 = Car("Chevy", "Volt", 15000.00, 10)
>>> car1.make
ib
Chevy
>>>car2 = Car("Ford", "Focus", 10000.00, 5)
>>> car2.make
tr
Ford
>>> car1.make
is
Chevy
>>> Car.wheels
4
D
>>>Car.calcMPG(120, 3.3)
36.36363636363637
>>>>>>car1.sellCar(3)
>>>car1.inventory
7
>>>
or
e
Properties
at
Unlike many other programming languages, Python classes are dynamic. That means any program Properties
lic
using the class can add, delete, or modify instance attributes on the fly. That can be somewhat Point out that properties
dangerous, as you lose control over just how the class you created is being used. provide more control
over class attributes.
To regain control over the attributes, Python provides properties. A property is a protected attribute
up
that can only be modified by using special instance methods called setters and retrieved by using
special class methods called getters.
To identify a property, start the attribute name with two underscores:
D
>>>class Car:
... def __init__(self, make):
o
data values are being changed. For example, in the setter, you could write code to make sure the data
value is in a valid format or within an appropriate range. You might trigger changes in other
attributes, too.
The Property Method The downside to using getters and setters is that now you need to remember and use separate
methods for each property and function that you need to use in your program. For programs with
lots of properties, that can be a lot of methods to use! To solve that problem, Python uses the
property method. With the property method, you define the getter, setter, and an optional deleter
method for the property:
e
... make = property(get_make, set_make, del_make)
You still need to define all of the getter, setter, and deleter methods in your class code, but at least
ut
now using them is much easier. The program can reference the property with just the property
name:
ib
>>> car1.make = "Chevy"
Python calls the appropriate getter or setter method to accomplish the function.
tr
Guidelines for Creating a Property
is
When you create one or more properties for a class, you must also create the getters and setters for
each property.
D
Create a Property
Create a Property
>>>class Car:
...
or
Use two underscores in front of each attribute name that you want to become a property:
When you create properties, create a getter method for each property. The getter method just
returns the value of the property to the calling program:
... def get_make(self):
D
For each property, create a setter method so that programs that use the class can change the value of
D
the property:
... def set_make(self, make):
... self.__make = make
... def set_model(self, model):
... self.__model = model
... def set_price(self, price):
... self.__price = price
Define a Property()
Define a Property() Method Method
After you define the getters and setters, you can combine them in property methods:
... make = property(get_make, set_make)
... model = property(get_model, set_model)
... price = property(get_price, set_price)
e
... inventory = property(get_inventory, set_inventory)
ut
Use the Property in an
Use the Property in an Instance Instance
To reference the class properties, don't use the underscores in the attribute, but instead use the
ib
property names:
>>>car1 = Car("Chevy", "Volt", 15000.00, 10)
tr
>>> car1.make
'Chevy'
is
>>> car1.make = "Ford"
>>> car1.make
'Ford'
D
>>>
Inheritance
or
When creating classes, you want to keep the class definition as generic as possible so that it can fit as
many application environments as possible. However, often you need to build onto a class definition
Inheritance
e
to fit a specific application environment.
at
Python allows you to do that with inheritance. Inheritance allows you to create a subclass from a main
class (called the superclass). A subclass contains (inherits) all of the original attributes and methods of
the superclass, plus adds its own attributes and methods specific to the subclass.
lic
To create a subclass, you must reference the superclass that it inherits when you define it:
>>> class Sedan(Car):
up
When you create the subclass, Python doesn't automatically call the constructor for the superclass,
so you must reference it in the constructor for the subclass:
>>>class Car:
D
...
>>>class Sedan(Car):
... def __init__(self, make, model, doors, seats):
N
...
>>>
D
The constructor for the Sedan subclass uses the super method to inherit the attributes and
methods of the superclass. This calls the __init__ method for the Car superclass, passing the
constructor values to the superclass.
The subclass can define its own methods, but it can also define the same methods as the superclass.
This is called overloading the method. If the same method is defined in both the superclass and the
subclass, objects created using the subclass use the overloaded method from the subclass, while
objects created using the superclass use the methods from the superclass.
e
>>>class Car:
ut
... def __init__(self, make, model, price, inventory):
... self.make = make
... self.model = model
ib
... self.price = price
... self.inventory = inventory
... def display(self):
tr
... print('{0} {1}'.format(self.make, self.model))
...
is
>>>class Sedan(Car):
... def __init__(self, make, model, price, inventory, doors, seats):
... super(Sedan, self).__init__(make, model, price, inventory)
D
... self.doors = doors
... self.seats = seats
...
Use the subclass name to instantiate new objects instead of the superclass name. Use the superclass
name to instantiate any objects that don't use the subclass, but instead use the superclass. Remember
that overloaded methods will behave differently for the subclass and superclass instances:
>>> sedan1 = Sedan("Ford", "Focus", 10000.00, 5, 4, 5)
D
>>> sedan1.display()
Ford Focus is a sedan with 4 doors and 5 seats
N
>>>car1.display()
Chevy Volt
>>>
o
Guidelines for Using Use the following guidelines to help when working with classes in your Python programs:
Object-Oriented Classes • Use classes to combine data and functions that are related.
in Python
• Define the class using the class statement.
• Define a constructor for the class using the __init__() method.
• Use class attributes for sharing values between instances.
e
parent objects.
• Create classes and subclasses in modules so that you can easily use them in your Python
ut
programs.
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 1-1
Creating an Object-Oriented Class
e
Ensure that Python version 3.4.2 and the PyCharm Community Edition IDE version 3.4.1 are
ut
installed on your computer.
Scenario
ib
You are developing Python applications that will be used by a local car dealer. You have been tasked
to create an application that maintains records of the vehicles in inventory. As you use object-
oriented programming classes in your Python applications, you'll want to save them in separate
tr
module files. Using PyCharm, you'll create a new project to build a module for handling the Car and
Sedan classes. You can then use that module in any Python application that requires those classes.
is
Activity: Creating an
Object-Oriented Class Note: Activities may vary slightly if the software vendor has issued digital updates. Your
D
Notify students of any instructor will notify you of any changes.
changes to activities
based on digital software
updates issued by the
software vendor.
1. Open PyCharm and create a new project.
or
a) From the desktop, double-click the JetBrains PyCharm Community Edition 3.4 shortcut.
b) In the PyCharm Community Edition window, select Create New Project.
e
Note: If you already have a project open, select File→Close Project from the
at
menu bar to open the PyCharm Community Edition window, then select
Create New Project.
c) In the Create New Project dialog box, in the Project name text box, type AdvPython
lic
d) Next to the Location field, select the Browse button to open the Select Location for Project Directory
dialog box.
e) In the top-left corner of the Select Location for Project Directory dialog box, select the Home
up
g) Beneath the Desktop directory, select the triangle next to the AdvPython directory to show
subdirectories beneath it.
h) Select the Using Object-Oriented Python directory, and select OK.
ot
Note: If you receive a message from Windows Firewall, select Allow Access. If
the Tip of the Day dialog box is shown, close it.
N
a) Enter the class definition statement, and define the constructor by adding the following code. If you would prefer that
you or your students not
type the code in step 3,
you can copy it from
SNIPPET 1, provided in
Snippets.txt.
e
ut
ib
b) Enter the setter and getter methods by adding the following code after the constructor.
tr
is
D
or
e
at
lic
up
Note: Alignment matters in Python. Please make sure your code is indented
as shown here.
D
c) Enter the property definitions for each attribute of the Car class by typing the following after the
getter and setter methods.
ot
N
o
D
d) Enter the display() and sellCar() methods by typing the following after the property
definitions.
e
ut
ib
4. Type the code to create the Sedan subclass in the cars.py file.
If you would prefer that a) After the Car class code, enter the code to create the Sedan subclass by typing the following.
tr
you or your students not
type the code in step 4,
is
you can copy it from
SNIPPET 1, provided in
Snippets.txt.
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 1-2
Using an Object-Oriented Class in an
Application
e
Before You Begin
ut
You have created the AdvPython project and the cars.py file. The AdvPython project is open in
PyCharm.
ib
Activity: Using an
Scenario Object-Oriented Class in
an Application
tr
Before you start writing the full application, you want to test out the Car and Sedan classes that you
previously built. You will create a new module to test creation and use of the new classes.
is
1. Create the cartest.py test file in the AdvPython project.
D
a) Right-click the AdvPython project in the PyCharm window.
b) Select New→Python File.
c) In the Name text box, enter the file name cartest
d) Select the OK button.
b) Type the following to create an instance of both the Car and Sedan classes.
If you would prefer that
you or your students not
D
Snippets.txt.
3. Enter code to perform some basic tests of the Car and Sedan classes.
N
a) Display both the Car and Sedan instance values using the display() method by typing the If you would prefer that
following. you or your students not
o
b) Simulate selling three cars by using the sellCar() method, then display the results by typing the
following.
c) Simulate changing the sedan information by changing the number of doors to 3. Do that by typing
e
the following.
ut
ib
tr
4. Run the cartest.py program to test it.
is
a) Select Run→Run.
D
or
e
b) In the pop-up window, select cartest.
c) Examine the output.
at
lic
up
D
ot
The first two lines show the car1 and sedan1 instance values that you defined. The third line
shows the result of the sellCar(3) method that you ran, and the fourth line shows the result of
N
TOPIC B
Use Magic Methods
Python provides a host of built-in methods that you can use with any class objects that you create.
These methods are often called magic methods, special methods, or helper methods. In this topic,
you'll explore what built-in magic methods are available, and how to use them in your programs.
e
ut
Constructor and Destructor Methods
The __init__ constructor method provides a way for an application to define initial values for Constructor and
ib
attributes when you instantiate it. The default format for a constructor method lists the attribute Destructor Methods
values as parameters, then assigns the parameter values to the attributes: Remind students of the
tr
>>> class Car: __init__ method
... def __init__(self, make, model, price, inventory): described in Topic A,
and explain that it is a
is
... self.make = make
constructor method.
... self.model = model
... self.price = price
D
... self.inventory = inventory
...
>>>
or
However, having to provide values for each parameter can be somewhat painful, especially if there
are any values that are often the same, such as the number of doors or seats on a sedan object. To
prevent having to enter common values, you can define default values inside the constructor
e
definition:
at
>>>
Another magic method that comes in handy is the destructor. The destructor method runs when you
delete an instance of the class. This allows you to perform some clean-up functions before the
instance goes away. This is especially handy if you have an application that opens lots of files. It's a
D
good idea to make sure all of the files are closed before the instance goes away.
The destructor uses the __del__ method:
ot
by Python as the program runs. You can manually delete a class instance at any time using the del
statement.
o
Note: Python will attempt to automatically remove unused class instances from memory when it
detects they are no longer in use in an application. However, for large applications that use a lot
D
of memory, it can be beneficial to manually delete the instance yourself to help increase
performance.
e
>>> class Car:
ut
... def __init__(self, make, model, price, inventory):
... self.make = make
... self.model = model
ib
... self.price = price
... self.inventory = inventory
...
tr
>>> car1 = Car("Chevy", "Volt", 15000.00)
Traceback (most recent call last):
is
File "<input>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'inventory'
>>>
D
Defining Default
Attribute Values Defining Default Attribute Values
Point out that initializing
all instance attributes in
the constructor also
enables you to write
programmatic checks to
or
If you don't want to have to define values for all of the attributes, define default attribute values in
the constructor. Then, any missing parameters are assumed to take their default values. A good
practice is to initialize all instance attributes in the constructor, even if they only create placeholders.
That will prevent exceptions for situations when an attribute doesn't exist:
e
examine attributes once >>> class Sedan(Car):
at
the object is created. ... def __init__(self, make, model, price, inventory, doors = 4, seats = 5):
... Car.__init__(self, make, model, price, inventory)
... self.doors = doors
lic
>>>sedan1.display()
This sedan has 4 doors and 5 seats
>>>
D
Guidelines for Using Use the following guidelines when deciding when to create constructors or destructors in your
Constructors and Python classes:
Destructors
• Create a constructor when you need to initialize attributes or properties in your classes.
N
• Use the del statement to remove a class object from memory when it's no longer needed in an
D
strings. Sometimes, it also comes in handy to be able to compare two objects, as well, but that can
get somewhat tricky.
Just how do you compare two Car class instances? There can be many attributes assigned to a class,
so it would be impossible for Python to know just which ones to compare:
>>> car1 = Car("Chevy", "Volt", 15000.00, 10)
>>> car2 = Car("Ford", "Focus", 10000.00, 20)
>>> if (car1 > car2):
... print("The Volt is bigger")
e
...
Traceback (most recent call last):
ut
File "<input>", line 1, in <module>
TypeError: unorderable types: Car() > Car()
>>>
ib
Python has no way to determine what the greater-than operation means when working with the Car
class objects. However, Python does provide a way for us to tell it just what to do. This is called a
tr
comparison method:
... def __gt__(self, other):
is
... if (self.price > other.price):
... return True
D
This code uses the price attribute of the Car class to determine if one Car object is greater than
another. Since it is a method, it returns a True boolean value if the condition is true. The magic part
of this method is that not only can you now use the __gt__ method for the class, you can also use
the actual greater-than symbol ( > ) to compare Car objects.
__eq__ Equal
__ge__ Greater-than or equal
lic
__gt__ Greater-than
__le__ Less-than or equal
up
__lt__ Less-than
__ne__ Not equal
D
You don't need to define all of the comparison methods in the class, only the ones you need to use
in your applications.
ot
Comparison methods provide a way for you to define how your classes will behave when
comparison operations are performed on them.
o
Working with
Working with Comparison Methods Comparison Methods
D
Define comparison methods after the constructor. You don't need to define all of the comparison
methods, just the ones that you need to use for your class:
>>> class Car:
... def __init__(self, make, model, price, inventory):
... self.make = make
... self.model = model
... self.price = price
e
... return True
ut
...
>>> car1 = Car("Chevy", "Volt", 15000.00, 10)
>>> car2 = Car("Ford", "Focus", 10000.00, 3)
ib
>>> if (car1 > car2):
... print("The {0} is more expensive than the {1}".format(car1.model,
car2.model)
tr
...
The Volt is more expensive than the Focus
is
>>>
>>> car1.price = 10000.00
>>> if (car1 == car2):
D
... print("Both cars are the same price")
...
Both cars are the same price
>>>
Numeric Methods
or
e
Remind students of how Python also includes several numeric operation magic methods that can come in handy. Numeric
at
Python handles integer methods enable you to define how your classes will behave when basic mathematical operations,
values and floating-point such as addition, subtraction, multiplication, and division, are performed on them, as treating the
values for numbers.
lic
classes as though they were simple numbers. Numeric methods also support some advanced
Numeric Methods mathematical operations, such as raising values to a power, or shifting values left or right.
Obviously, not all classes need to support all of the numeric magic methods, but they're available to
up
use if you need them. For our Car class, say you want to be able to find out the price difference
between two cars. To do that, you first need to define the __sub__ method in your Car class:
... def __sub__(self, other):
... return self.price - other.price
D
...
Then, you can easily subtract one car from another, implying that it’s actually the price you want to
ot
subtract:
difference = car1 – car2
N
As you can guess, Python provides numeric magic methods for most of the common mathematical
operations you'll run into.
List of Numeric Methods
o
__add__ Addition
__and__ Boolean AND
__div__ Division
__divmod__ Division modulo
__floordiv__ Returns the integer part of the division
e
__rshift__ Shifts the number right
ut
__sub__ Subtraction
__xor__ Boolean XOR
ib
Just as with the comparison methods, you don't need to define all of the numeric methods for your
classes, just the ones you think you'll need to use in your applications.
tr
is
Guidelines for Working with Numeric Methods
Numeric methods provide a way for you to define how your classes will behave when simple
D
mathematical operations are performed on them.
Working with Numeric
Working with Numeric Methods
or
Just as with comparison magic methods, you only need to define the numeric magic methods that
you think you'll need to use for the class objects. Just define them anywhere after the constructor
method:
Methods
e
>>> class Car:
at
ACTIVITY 1-3
Creating a Class Constructor and Destructor
e
You have created the AdvPython project with cars.py and cartest.py. The AdvPython project is
ut
open in PyCharm.
Activity: Creating a
Class Constructor and Scenario
ib
Destructor
You will now add a constructor to the Sedan class that assumes default values for the doors and
seats attributes in the constructor. You will also add a destructor method in the Sedan class that
tr
displays the final values of the sedan instance before it is deleted.
is
1. In cars.py, edit the Sedan constructor to add default values.
a) In cars.py, scroll down to the Sedan class definition area.
D
b) Modify the __init__ function to set the default value of the doors parameter to 4 and the seats
parameter to 5
or
e
at
lic
section that uses the print method to display the instance values of all the attributes.
D
ot
N
o
D
a) Select Tools→Run Python Console from the PyCharm menu bar. The Python Console window
should appear at the bottom of the PyCharm window.
e
ut
b) In the Python Console, import all of the classes from the cars.py module file by typing the following.
ib
tr
is
D
c) Create an instance of the Sedan class, but don't specify the number of doors or seats by typing the
following.
or
e
at
lic
e) Use the del method to destroy the sedan1 instance you created.
N
o
D
f) Try to display the sedan1 instance to verify that it no longer exists. You will get an error message
that looks like the following.
e
ut
4. Close the console.
a) Select the Close button to close the console.
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 1-4
Working with Comparison and Numeric Magic
Methods
e
Before You Begin
ut
You have created the AdvPython project with cars.py and cartest.py. You have modified the
constructor and added a destructor to cars.py. The AdvPython project is open in PyCharm, and
ib
cars.py is open for editing.
Activity: Working with
Scenario Comparison and
tr
Numeric Magic Methods
You will add methods to the Car class that enable you to compare prices on cars. You will add a
check for greater-than, less-than, and equal to the class definition.
is
D
1. Edit the Car class to add the new methods.
a) Following the __init__ method definition, add new definitions for the __eq__, __gt__, and
__lt__ methods as shown.
b) Import the Car class from the cars.py module file by typing the following.
e
c) Create two instances of the Car class, one more expensive than the other.
ut
ib
tr
is
D
d) Check if both of the Car instances have the same price by using an if-then statement and a
print statement as shown.
or
e
at
lic
Note: You must press Enter twice after the second line to return to the >>>
prompt.
up
Since the car prices are not the same, the if-then statement fails, and the print statement is
skipped.
e) Test if the first car is more expensive than the second car by typing the following.
Remind students to
D
TOPIC C
Incorporate Class Factories
Object-oriented programming is all about consistency. The more your class definitions use standard
formats and interfaces, the more useful they'll be to use in a wider variety of applications. One of
the standards that helps Python programmers share classes is class factories. The class factory can
e
help you define a standard for classes and subclasses that makes it easier to implement them in your
ut
Python applications.
ib
In a large Python application that uses several classes and subclasses, it's easy to get lost in a sea of Simple Class Factory
tr
class definitions. Trying to remember just what subclasses belong to which classes can be confusing.
Fortunately, you can use an advanced object-oriented feature called class factories to help keep things
straight.
is
A simple class factory gathers all of the subclasses that belong to the same superclass together into a Point out that class
single class definition. The factory provides one-stop shopping to instantiate any of the subclasses factories are often used
D
from a single class method. While this may sound confusing, it actually can help keep your in web development
subclasses in order, and help you to easily find just the right subclass for your application. frameworks, like Flask
®
and Django .
or
The key to a class factory is the factory method that you define for the superclass object. The
factory method uses a single parameter—the name of the subclass that you want to instantiate.
Based on the parameter, the factory instantiates the requested subclass object. The code to
implement a simple class factory looks like the following:
e
class Car:
at
def factory(type):
class Sedan(Car):
def display(self):
lic
return Sports()
With this approach, you can group all of the subclass definitions together in the factory class for
easy access to any subclass.
ot
Often, subclasses overload the same class methods, tweaking the methods so that they incorporate Polymorphic Class
the differences related to each subclass. Trying to keep track of all the overloaded methods for each Factory
o
subclass can be yet another object-oriented programming nightmare. It would be nice to be able to
call a single method in your programs to retrieve the information specific to the subclass that you're
D
working with.
The polymorphic class factory enables you to call a single method to instantiate any subclass from a
superclass. The polymorphic class factory references all of the overload methods in subclasses, and
uses the correct one based on the subclass that was instantiated. There's no need to worry about
using the correct method for the correct subclass. The polymorphic class factory does that for you.
Assume that you have two subclasses that overload the same method:
class Sedan(Car):
def display(self):
print("This is a sedan")
class Sports(Car):
def display(self):
print("This is a sports car")
Both the Sedan and Sports subclasses define the display() method, and each one does
something different. You can now create a polymorphic class factory method that calls the
e
appropriate subclass display() method based on the subclass of the object being used:
ut
def displayCar(carType):
carType.display()
ib
Now you can create multiple objects of different subclasses and call the same displayCar()
method to run the display() method for any of the subclasses.
tr
Abstract Class Factories
is
Abstract Class Factories You may run into situations where the superclass used for an object isn't used to create any
—The Need instances; all of the object instances in the application are created using subclasses. Because of that,
D
there isn't any reason to create a detailed class definition for the superclass. Each subclass just
defines the attributes and methods that it needs:
>>> class Car:
...
...
pass
...
>>> class Sports(Car):
... def displayCar(self):
lic
Notice, though, that the two separate subclasses use different methods to display the object
information. Because of that, if you accidentally use the wrong method for a subclass, you'll get an
error message:
D
>>> car1.displayCar()
Traceback (most recent call last):
File "<input>", line 1, in <module>
ot
Abstract Class Factories To avoid this situation, you can create an abstract class factory. The abstract class factory creates the
N
—The Solution superclass with abstract templates for any method that you want to use for subclasses. You don't use
any code here, other than to provide an error message to display if the method isn't overloaded by
the subclass:
o
class Car:
D
def displayCar():
print("Sorry, this method is not implemented")
def sellCar():
print("Sorry, this method is not implemented")
Each subclass definition must overload all of the methods defined in the abstract class factory. If
any methods aren't overloaded and a program attempts to use them, the superclass method takes
over and displays an error message.
e
>>> car1 = Car.factory("Sedan")
>>> car1.display()
ut
This car is a sedan
>>>
ib
Polymorphic Class Factory
With polymorphic class factories, you can define the same method for different objects and Python
tr
will use the appropriate class method for each object:
>>> car1 = Sedan()
is
>>> car2 = Sports()
>>> displayCar(car1)
D
This is a sedan
>>> displayCar(car2)
This is a sports car
>>>
• Create a simple class factory when you have multiple subclasses and want to easily manage them Class Factories
from the superclass.
• When creating a simple class factory, create a factory method in the superclass.
ot
• When creating a simple class factory, create the subclasses inside the factory method.
• Ensure that the factory method creates the appropriate subclass object based on the parameter
N
passed to it.
• When creating a polymorphic class factory, create a separate method for each overloaded
method in the subclasses.
o
• Ensure the polymorphic method runs the appropriate subclass overload method based on the
parameter passed to it.
D
• When creating an abstract class factory, ensure you create method templates for all of the
overloaded methods used in subclasses.
• Ensure the superclass method templates produce some type of error message or signal if a
subclass doesn't overload the method.
ACTIVITY 1-5
Creating a Class Factory
e
The AdvPython project is open in PyCharm.
ut
Activity: Creating a
Class Factory Scenario
Create a simple class factory that can create a Sedan or Sports subclass object using a single factory
ib
method defined in the Car superclass. Don't worry about adding attributes or extra methods for this
exercise; focus on the factory method and how to allow it to create subclass objects.
tr
is
1. Create the carfactory.py file in the AdvPython project.
a) In the left window, right-click on the AdvPython project name.
b) From the menu, select New →Python file.
D
c) In the Name text box, type carfactory
d) Select the OK button to create the file.
provided in Snippets.txt.
up
b) Under the factory() definition, type the code to create the Sedan subclass.
D
ot
N
o
This class contains a single method named display() that just displays some text indicating that
the method has been run, as shown.
D
e
ut
ib
tr
This class also includes a single method named display() that just displays some text indicating
that the method has been run.
is
d) Finish the factory() method code by adding two if statements that test the type attribute and run
the appropriate subclass.
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 1-6
Using Class Factories in an Application
e
The AdvPython project is open in PyCharm. The carfactory.py file is open in an editing tab.
ut
Activity: Using Class
Factories in an Scenario
Application
You will write code that uses a class factory to generate a Sedan and a Sports subclass object, and
ib
you will use the display() method to test which object is which.
tr
1. Write code to instantiate and display two different classes of car.
is
a) In carfactory.py, skip a line after the end of the Car class definition, then write statements to create
a Sedan and Sports car, using the Car class' factory() method.
D
or
e
b) Skip a line and write statements to call the display method for each car.
at
lic
up
The sedan1 object displayed the message for a sedan, and the sports1 object displayed the
message for a sports car.
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
Summary
In this lesson, you used object-oriented programming to help organize data and functions in your
Python programs. Object-oriented classes and subclasses make it easier to reuse code that describes
common objects between programs without having to rewrite code. You also used built-in Python
magic methods in your class definitions to provide extended functionality to your own classes and
subclasses. Finally, you used class factories to help organize complex class objects in programs.
e
Encourage students to
use the social What type of objects would be best to use for creating classes?
ut
networking tools A: Answers will vary. Objects that you use in multiple applications are the best candidates for converting
provided on the CHOICE into classes. The more times you use an object in different applications, the more time you save by
Course screen to follow not having to retype the code to define attributes and methods required for the object. If you only use
ib
up with their peers after
an object in a single application, there's not much time or work savings to benefit from.
the course is completed
for further discussion How can a large corporation benefit from implementing object-oriented Python programming?
tr
and resources to support
continued learning. A: Answers will vary. Since the key to getting the most out of object-oriented programming is reuse, the
best way for a company to benefit from object-oriented programming is to encourage their entire
is
programming staff to share objects they create. As programmers create classes for applications, they
should store the class module file in a common location for others to use. A shared code library of
D
classes and subclasses can save lots of programming time for large applications.
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
or
peers, and the larger CHOICE online community about the topics covered in this course or
other topics you are interested in. From the Course screen you can also access available
resources for a more continuous learning experience.
e
at
lic
up
D
ot
N
o
D
e
Lesson Time: 3 hours, 15 minutes
ut
ib
tr
Lesson Objectives
is
In this lesson, you will:
D
• Define how graphical applications work.
• Create a graphical interface for an application.
or
• Create methods for handing user events and data in a graphical window.
Lesson Introduction
e
at
Often, when you hear the term "Python® scripting," the first thing that comes to mind is
boring command-line scripts. However, these days, just about every operating system
incorporates some type of graphical user interface (GUI) to enable users to input data and
lic
view results. You can leverage the graphical desktop environment with your Python scripts
to create a fancy, windows-oriented interface for your programs that will help give your
scripts a more professional look and feel.
up
D
ot
N
o
D
34 | Python® Programming: Advanced
TOPIC A
Design a GUI
You've created Python applications that run in a console window, but now you want to create
something a bit more sophisticated—an application that runs in a Windows®-style user interface,
complete with buttons, text boxes, check boxes, and so forth.
e
You may want show the
ut
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
from the CHOICE course screen.
Course screen or have
ib
students navigate out to
the Course screen and GUI Libraries
watch them as a
tr
supplement to your A lot of people have worked hard to simplify graphical user interface (GUI) programming in the
instruction. If not, please Python environment. Standard library packages help you create GUI widgets from your Python
is
remind students to visit scripts and build your graphical programs. The following are some of the more popular Python GUI
the Spotlights for this
libraries.
course on their CHOICE
D
Course screen after
class for supplemental Library Description
information and tkinter Uses the TK graphical library and is the default GUI library included as part
additional resources.
GUI Libraries
Point out that the
standard Python library
PyGTK or
of the standard Python suite.
Uses the GTK+ graphical library, used mainly in the GNOME desktop
environment in Linux®.
e
includes the tkinter
package by default, so PyQT Uses the Qt graphical library, which is used mainly in the KDE desktop
at
User Interface Objects When you make the move to GUI programming, you need to learn a new set of terms. For example,
This section defines the main area in a window is typically called the frame. The frame contains all of the objects the
standard Windows terms program uses to interact with the user, and it is the central part in a GUI program. The frame is
ot
as used by Python. composed of objects called widgets (short for window gadgets) that display and retrieve information.
Some students may be Most graphical programming languages provide a library of widgets for you to use in your programs.
familiar with other Although not an official standard, a common set of widgets is available in just about every graphical
N
Widget Description
Menu Displays a menu toolbar at the top of the window.
Progress bar Indicates that something is happening in the background.
Radio button Allows the user to select one item from a group.
Scroll bar Controls the viewed items in a list box or frame.
Separator Places a horizontal or vertical bar in the window.
e
Spin box Allows a user to select a value from a range of numbers.
ut
Text Provides a large area to enter or display multiple lines of text.
ib
Each widget has its own set of properties that define how it appears in the window and how to
handle any data or actions that occur while the user interacts with the widget. Before you start to
code your user interface, it's a good idea to plan your layout on paper or in a wireframe drawing tool.
tr
Guidelines for Planning a User Interface
is
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
D
CHOICE Course screen.
Use the following guidelines to help when planning a graphic user interface design. Guidelines for Planning
• To identify the widgets you require:
• Determine what data the application needs to collect from the user. or
• Determine the most appropriate widget to use for each data value the user must provide. (For
a User Interface
e
example, use a radio button when the user should select a single object from a group of
options.)
at
• Determine what actions will trigger the processing of the input data, and what widgets will be
involved. (For example, the user selects a Calculate price button.)
lic
• Provides a look and feel that you and your users will like to use.
• Provides licensing options that are acceptable for your purposes.
• Is compatible with all of the operating systems and distribution methods you need to support
D
ACTIVITY 2-1
Designing a GUI
Scenario
e
You've been asked to design an application, the Python Pizza Calculator, which helps customers
ut
of a pizza restaurant determine the cost of the type of pizza they are interested in ordering. To do
that, you'll need to create a window with widgets to allow customers to select the size of pizza they
want (medium, large, or extra large), along with choosing from a list of available toppings. Once
ib
customers select their pizza options, they'll be able to view the total cost for the pizza.
Activity: Designing a GUI The user interface will include some means to do the following:
tr
• Choose a size (just one):
• Medium
is
• Large
• Extra Large
D
• Choose toppings (none, one, or more than one):
• Sausage
• Pepperoni
• Chicken
• Mushroom
• Onion
or
e
• Black Olive
at
• Green Pepper
• Red Pepper
• Clear all selections (reset).
lic
1. Consider the following questions as you plan the layout for the Python Pizza Calculator.
Discuss these questions
with the entire class or 2. How many windows will the application use?
consider dividing
D
A: While applications may have multiple windows, this application is simple enough that it can be
students into teams. implemented in one window.
Consider having
students use Paint,
ot
® 3. What type of widget(s) might you provide to enable the user to select a pizza size?
PowerPoint , or a
wireframe diagramming A: Since only one size should be selected from the three options, a group of radio buttons is probably
tool to design the layout, the most appropriate choice for this. Another option would be a list box configured to allow only
N
A: Since no selection, one selection, or multiple selections should be allowed, a group of check
boxes would be an appropriate choice for this. Another option would be a list box configured to
D
5. What type of widget(s) might you provide to enable the user to clear (reset) the selections?
A: A button would be appropriate for this. When selected, a Reset button could trigger an action that
resets the application widgets back to their original selection states.
6. What type of widget(s) might you provide to enable the user to calculate the total?
A: A label or text box could be used to display the resulting price. There are different ways to trigger
the calculation. For example, you might calculate a new result automatically each time the user
changes the size or toppings. Or you might provide a separate Calculate price button that displays
the updated total when the user selects the button.
e
PPC Wireframe
ut
After students complete
their diagrams, have
them present them to
the group and/or display
ib
the slide showing an
example wireframe
tr
diagram.
While there are various
ways to implement the
is
user interface, point out
that the slide represents
D
the design that will be
used in the activities that
follow.
or
e
at
lic
up
D
ot
N
o
D
TOPIC B
Create and Arrange a GUI Layout
Once you've come up with a layout for your GUI application and have selected a GUI library that
you'll use to develop it, you're ready to start programming your layout.
e
Tkinter Library
ut
Tkinter Library The tkinter library provides a standard class and methods for creating windows and widgets. Just
import all of the items in the tkinter module, and instantiate the Tk() class:
ib
from tkinter import *
window = Tk()
tr
window.title("This is a test window")
window.geometry("300x100")
is
This code creates a window, and sets the title and size of the window, which is straightforward.
However, before you can add widgets to the window, you must create a frame by defining a subclass
D
of the tkinter Frame class:
class Application(Frame):
def __init__(self, master):
self.create_widgets()
window = Tk()
or
super(Application, self).__init__(master)
e
window.title("Test Application Window")
at
window.geometry("300x100")
app = Application(window)
app.mainloop
lic
This code template defines the class Application as a subclass of the tkinter Frame class. It then
uses the empty Tk() instance as the parent class for the app instance.
After instantiating the new window, the mainloop() method is called. It enters into an endless
up
loop, listening for window events, and passing them to event handler methods defined in the
program.
D
You must create a single method that creates all of the widget objects in the frame. First, define the
method name in the Application constructor:
class Application(Frame):
o
super(Application, self).__init__(master)
super.create_widgets()
Define Labels
Define Labels
To place text in the window, use the Label widget. The Label widget uses a single parameter
named text to define the text placed in the window:
self.text1 = Label(self, text="This is the text in the window")
Define Buttons
Define Buttons
The Button widget provides a way for application users to trigger event handlers in the application,
e
such as to let the program know when there's data to submit. You must assign the Button widget to
ut
a unique variable created in the Application subclass. The Button widget uses two parameters—
the text that's placed inside the button, and the command parameter, that defines the method that's
called when the button is pressed:
ib
self.button1 = Button(self, text="Submit", command=self.calculate)
tr
Define Entry Widgets
The Entry widget is one of the most versatile widgets you'll use in your programs. It creates a
is
single-line form field that the user can use to enter text to submit to the program, or your program
can use to display text dynamically in the window. The Entry widget doesn't require any parameters,
D
but often the width parameter is used to set the number of characters to place in the viewable area
(you can enter more characters in the Entry form field, as they will scroll within the field):
self.entry1 = Entry(self, width=20)
width and height of the text box that it creates in the window:
self.field1 = Text(self, width=20, height = 10)
lic
are normally grouped together to form a group of options where only one option from the group
can be selected. Use the text parameter to specify the label that appears next to the radio button,
and the value parameter to specify the value that's passed to the event handler when the radio
D
button is selected. To specify which radio buttons are grouped together, you use the variable
parameter to specify the same variable for the group of buttons:
self.button1 = Radiobutton(self, text="Option 1", variable=result, value="1")
ot
checked by the user, it returns a True value, and if the widget is not checked, it returns a False
value. The parameters for the Checkbutton widget are text to display the label that appears next to
D
the check box, and variable, to define the variable that returns the Checkbutton state:
self.option1 = Checkbutton(self, text="Option 1", variable=option1)
lists, you can easily use a list to contain the options, and use a loop to iterate through the list and
create the Checkbutton lines. To do that, you'll need to create a separate list to hold the individual
Checkbutton widget objects, and the variables that they each return. This can get a little confusing,
but using some common-sense list names helps:
self.options = ["Option 1", "Option 2", "Option 3", "Option 4"]
self.checkbox = list(self.options)
self.checkboxVar = list(self.options)
for option in range(len(self.options)):
self.checkbox[option] = Checkbutton(self,
e
text=options[option],
ut
variable=self.checkboxVar[option])
ib
Window Positioning The key to a user-friendly GUI application is the placement of the widgets in the window area. Too
tr
Methods many widgets grouped together can make a user interface confusing. The tkinter package provides
three ways to position widgets in the window:
is
• Packing widgets into available spaces in the window
• Using positional values
D
• Using a grid system
The packing method pretty much does what it says. It attempts to pack widgets into a window as best
it can in the space available. When you choose this method, Python places the widgets in the
or
window for you, starting at the top-left of the window and moving along to the next available space,
either to the right or below the previous widget. The packing method works fine for small windows
with just a few widgets, but if you have lots of widgets, things can get pretty cluttered.
e
The positional method requires that you define the precise location of each widget, using X and Y
coordinates within the window. This provides the most accurate control over where the widgets
at
creates a grid system in the window using rows and columns, somewhat like a spreadsheet. You
place each widget in the window at a specific row and column location:
self.text1 = Label(self, text="This is some window text")
up
self.text1.grid(row=0, column=0)
You can also define a widget to span multiple rows or columns:
self.text1.grid(row=0, columnspan=3)
D
The grid method also defines the sticky property. This determines where in the cell the widget is
positioned (N for top-aligned (north), S for bottom-aligned (south), E for right (east), and W for left
(west).
ot
and-paper approach to plan columns and rows where widgets should appear. For developers
coming from visual layout environments like Xcode® or Visual Studio®, this approach seems
familiar.
o
• It tends to adapt the layout well when the window size is changed by the user.
D
class Application(Frame):
def __init__(self, master):
super(Application, self).__init__(master)
super.grid()
super.create_widgets()
• Define the grid location for each widget as you create it:
def create_widgets(self):
self.label1 = Label(self, text="Welcome to my window")
e
self.label1.grid(row=0, column=0, sticky=W)
self.button1 = Button(self, text="Click me!", command=self.display)
ut
self.button1.grid(row=1, column=0, sticky=W)
self.output = Entry(self, width=10)
self.output.grid(row=2, column=0, sticky=W)
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 2-2
Creating the Python Pizza Calculator GUI
Application Window
e
Scenario
ut
You have settled on a layout for the Python Pizza Calculator window. You will start by creating a
new project folder. Then, you will develop the layout using the tkinter library.
ib
Activity: Creating the
Python Pizza Calculator
GUI Application Window 1. Launch PyCharm and create a new project.
tr
a) From the desktop, double-click the JetBrains PyCharm Community Edition 3.4 shortcut.
b) In the PyCharm Community Edition window, select Create New Project.
is
c) In the Create New Project dialog box, in the Project name text box, type PizzaCalculator
d) Next to the Location field, select the Browse button to open the Select Location for Project Directory
D
dialog box.
e) In the top-left corner of the Select Location for Project Directory dialog box. select the Home
beneath it. or
f) Under your user name, select the triangle next to the Desktop directory to show subdirectories
g) Beneath the Desktop directory, select the triangle next to the AdvPython directory to show
e
subdirectories beneath it.
h) Beneath the AdvPython directory, select the Creating a GUI directory.
at
k) On the left side of the PyCharm window, in the Project window, verify that PizzaCalculator is listed.
b) After the class definition, type the code to create the constructor.
If you would prefer that
you or your students not
type the code in step 3b,
you can copy it from
SNIPPET 1, provided in
Snippets.txt.
e
ut
ib
tr
is
D
or
e
at
The constructor defines a list object that contains the pizza toppings, and list objects for the
checkbuttons and the checkbutton variables.
lic
following code.
If you would prefer that
you or your students not
D
b) Add the code to define the three radio buttons used to select the pizza size.
If you would prefer that
you or your students not
type the code in step 4b,
you can copy it from
SNIPPET 3, provided in
Snippets.txt.
e
ut
ib
tr
is
D
or
All of the buttons will be on the same line, and will be tied to the same variable. The Radiobutton
e
select() method is called to make the Medium the default size selection.
c) Add the code to create a new label to identify the pizza toppings list, and the code to iterate through
at
Snippets.txt.
D
ot
N
A separate variable is used to keep track of the row numbers dynamically in the loop.
o
D
d) After the checkbox loop, add the code to create the two buttons to reset the form, and calculate the
pizza price.
If you would prefer that
you or your students not
type the code in step 4d,
you can copy it from
SNIPPET 5, provided in
Snippets.txt.
e
ut
ib
e) After the buttons, add code to create an empty line in the grid layout by creating a Label with no
text.
tr
If you would prefer that
you or your students not
is
type the code in step 4e,
you can copy it from
SNIPPET 6, provided in
D
Snippets.txt.
or
f) Finally, after the empty line, add code to set the Total label, and an Entry box to display the total
price.
e
If you would prefer that
you or your students not
at
Snippets.txt.
up
D
5. Now that you've completed the Application subclass, instantiate the Tk() class, create the
Application subclass instance, and start the main loop. Add code to set the window title and size.
ot
Note: You may have to experiment with the width and height settings depending
on your desktop default fonts.
e
ut
ib
tr
is
D
or
e
b) Select the different pizza size radio buttons to make sure you can only make one selection.
at
c) Select and deselect each toppings' check box to make sure they all work.
For now, nothing will happen when you select the Reset or Calculate Price buttons, as you haven't
defined any event handlers.
lic
a) In the top-right corner of the window, select the X to close the window and end the program.
up
D
ot
N
o
D
TOPIC C
Interact with User Events
You have created a window that contains various user interface components (widgets). Now, you
will populate those components with content and enable them to interact with the user.
e
Events
ut
Programming for a GUI environment is a bit different from command-line programming. In a Events
command-line program, the order of the program code controls what happens next. For example,
ib
the program has code that prompts the user for input, then processes the input, and then displays
the results on the command line based on the input provided. The user can only respond to the
tr
input requests as they are presented by the program.
In contrast, a GUI program displays an entire set of interaction widgets all at once, all in the same
is
window. The program user gets to decide which widget gets processed next. Because the program
doesn’t control which widget is activated at any given time, this process is called event-driven
programming. In event-driven programming, Python calls different methods within the program,
D
based on which event (or action) occurs in the GUI window. There isn’t a set flow to the program
code; it’s just a bunch of methods that individually run in response to an event.
or
For example, your user can enter data into a text widget, but nothing happens until the user presses
a button in the program window to submit the text. The button triggers an event, and your program
code must detect that event and then run the code method to read the text in the text widget and
process it.
e
at
Event Handlers
The key to event-driven programming is linking widgets in the window to events, and then linking Event Handlers
lic
events to code methods in the program. These methods are called event handlers. You must create
separate event handler methods for each event that can be generated from the widgets in the
window. The event handlers do the bulk of the work in GUI programs. They retrieve the data from
up
the widgets, process the data, and then display the results in a window using other widgets. This
might seem a bit cumbersome at first, but once you get used to coding with event handlers, you’ll
see just how easy it is to work in a GUI environment.
Event handlers are class methods created in the Application subclass that handle events generated
D
by widgets. You must define the event handler name inside the widget using the command parameter:
self.button1 = Button(self, text="Submit", command=self.display)
ot
The actual event handler is a separate method that you must create inside the Application
subclass:
N
def display(self):
print("The button was clicked")
It's imperative that you match the command name defined in the widget to the method name,
o
Respond to a Button
Click Respond to a Button Click
When you create a Button widget, use the command parameter to define the event handler method
that Python will call when the program user selects the button:
self.button1 = Button(self, text="submit", command=self.display)
e
object. You can also display data from your program in an Entry widget by using the insert()
ut
method, or clear out any text already in the Entry widget by using the delete() method. The
delete() method uses two parameters—the starting character position (with the first character at
position 0), and the end position (you can use the special keyword END). The insert() method also
ib
uses two parameters—the starting location of the inserted text, and the text to insert into the widget:
def convert(self):
tr
varText = self.text1.get()
varReplaced = varText.upper()
is
self.text1.delete(0, END)
self.text1.insert(END, varReplaced)
D
Returned by a Determine the Value Returned by a Radiobutton Widget
Radiobutton Widget
Radiobutton widgets must use a control variable to pass the radio button state. Python defines four
types of control variables:
or
• BooleanVar()—for Boolean True and False values.
• DoubleVar()—for floating point values.
e
• IntVar()—for integer values.
• StringVar()—for text values.
at
Group radio buttons together by using the same control variable for each radio button in the group.
To retrieve the value of the selected radio button from the group, use the get() method for the
control variable. The get() method retrieves the value parameter specified for the selected
up
Radiobutton object:
def create_widgets(self):
self.var1 = StringVar()
D
value=”2”)
self.radio3 = Radiobutton(self, text=”Option 3”, variable=self.var1,
value=”3”)
N
def process(self):
selection = self.var1.get()
if (selection == “1”):
o
def create_widgets(self):
for i in range(len(self.options)):
self.checkboxVar[i] = BooleanVar()
self.checkbox[i] = Checkbutton(self, text=self.options[i],
variable=self.checkboxVar[i])
def process(self):
for box in range(len(self.options)):
if (self.checkboxvar[box].get()):
e
print(“%s was selected”.format(self.options[box]))
ut
Read the Value Entered
Read the Value Entered into a Text Widget into a Text Widget
As with the Entry widget, you retrieve text from the Text widget using the get() method, remove
ib
text using the delete() method, and add text using the insert() method. However, there’s a bit
of a twist to these methods in the Text widget. Because the widget works with multiple lines of text,
tr
the index value you specify is not a single value. Instead, it’s a text value that has two parts: "x.y".
The x is the row location (starting at 1), and y is the column location (starting at 0). So, to reference
is
the first character in the Text widget, you use the index value of "1.0":
def create_widgets(self):
self.text1 = Text(self, width=20, height=10)
D
def process(self):
varText = self.text1.get("1.0", END)
varReplaced = varText.upper()
self.text1.delete("1.0", END)
self.text1.insert(END, varReplaced)
or
e
Menu Bars
at
A staple of GUI programs is the menu bar at the top of the window. The menu bar provides drop- Menu Bars
lic
down menus so program users can quickly make selections. You use the Menu widget to create menu
bars in your tkinter programs.
First, define a main Menu instance. After that, you can add main menu bar top-level entries by
up
creating subclass instances of the main Menu instance. For menu entries that contain sub-menus, use
the add_cascade() method to add the entry. For menu entries that point directly to event handlers,
use the add_command() method.
D
menubar = Menu(self)
filemenu = Menu(menubar)
filemenu.add_command(label="New", command=self.new)
ot
filemenu.add_command(label="Open", command=self.open)
filemenu.add_command(label="Quit", command=self.quit)
menubar.add_cascade(label="File", menu=filemenu)
N
menubar.add_command(label="Help", command=self.help)
window.config(menu=menubar)
o
• If you allow your program users to enter free-form data into entry or text form fields, always
validate the entered data before using it in your application:
• For numeric fields, check that all of the characters are numbers using the Python
isnumeric() method.
• Also for numeric fields, validate the number of digits if necessary, such as the number of
digits needed for zip codes.
• For text fields, check for special characters, such as backslashes and semicolons. These are
often used to fool databases into performing unwanted actions.
e
• If your application supports HTML text, watch for embedded URL addresses in the data that
can lead other users to inappropriate websites.
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 2-3
Creating a Simple Window Form
e
The PizzaCalculator project is open in PyCharm.
ut
Activity: Creating a
Scenario Simple Window Form
You are considering adding a form to the Python Pizza Calculator to enable users to provide
ib
delivery instructions. You will create a new window that prompts the user to provide the delivery
information.
tr
is
1. Create the deliveryform.py file in the PizzaCalculator project.
a) In the left window, right-click on the PizzaCalculator project name.
b) From the menu, select New→Python file.
D
c) In the Name text box, type deliveryform
d) Select the OK button to create the file.
provided in Snippets.txt.
up
b) After the class definition, type the code to create the constructor.
D
ot
N
o
D
The application will use the grid positioning method, and will use create_widgets() to define the
widgets.
a) Define the create_widgets() method, and a menu bar that has two top-level entries: File and
Quit. The File entry will have a sub-entry named Submit.
If you would prefer that
you or your students not
type the code in step 3a,
you can copy it from
SNIPPET 10, provided
in Snippets.txt.
e
ut
ib
b) Inside the create_widgets() method, define the label that prompts the user to enter the delivery
instructions, the Entry widget to accept the input, and the Submit button to trigger the event
tr
handler called process. After those items are created, add a line to add the menu bar item to the
window.
is
If you would prefer that
you or your students not
type the code in step 3b,
D
you can copy it from
SNIPPET 11, provided
in Snippets.txt.
or
e
at
lic
up
4. After the constructor code, define the process event handler that retrieves the instructions entered into
D
the Entry widget, creates a message string, and displays the message in the output Entry widget.
If you would prefer that
you or your students not
ot
in Snippets.txt.
o
D
5. Add the code to instantiate the Tk() class, and the Application subclass, defining the window title
and size. Then, add the mainloop() method to listen for events.
If you would prefer that
you or your students not
type the code in step 5,
you can copy it from
SNIPPET 13, provided
in Snippets.txt.
e
ut
6. Run the deliveryform application.
a) Run the deliveryform.py script.
ib
The Pizza Delivery Instructions window is shown, and the text box is ready for you to type delivery
instructions.
b) Type knock twice (the doorbell is broken)
tr
c) Select the Submit button, or select File→Submit from the application menu bar. The message
appears at the bottom of the window.
is
D
or
e
d) Close the Pizza Delivery Instructions window to exit the application and return to PyCharm.
at
ACTIVITY 2-4
Adding Data Processing to the Python Pizza
Application
e
Before You Begin
ut
The PizzaCalculator project is open in PyCharm.
Activity: Adding Data
ib
Processing to the Scenario
Python Pizza Application
You have laid out the controls for the Python Pizza Calculator, but at this point, they are not yet
tr
functional. You will add an event handler to calculate the cost of the pizza based on the selections
the program user makes from the size and toppings widgets. The pizza cost will be based on a
Medium pizza being $9.99, with each additional topping $1.00, a Large pizza being $12.99, with each
is
additional topping $1.50, and an Extra Large pizza being $14.99, with each additional topping $1.80.
A dictionary object that holds the pizza prices for the calculations has already been added to the
D
project.
The dictionary uses the product description as the key and the price as the value.
ot
a) Add command parameters to the Reset and Calculate Price button widgets to point to the methods
that will handle their button clicks.
e
ut
ib
3. Define the reset() method to clear the total field form, select the Medium pizza size, and deselect all
tr
of the Checkbutton widgets.
a) After the create_widgets() method, but before the code to instantiate the window, insert a new
is
reset() method, as shown.
If you would prefer that
you or your students not
D
type the code in step 3,
you can copy it from
SNIPPET 14, provided
or in Snippets.txt.
e
at
This method selects the Medium pizza size, deselects each of the topping Checkbuttons, and
lic
a) After the reset() method, but before the code to instantiate the window, add a new calculate
method, as shown.
If you would prefer that
you or your students not
type the code in step 4,
you can copy it from
SNIPPET 15, provided
in Snippets.txt.
e
ut
ib
tr
is
D
• Lines 90 through 93 determine how many toppings were selected by iterating through all of the
Checkbutton variables in the list, using the get() method to determine if they are checked or
not. Self.totalToppings keeps a running total.
•
•
or
Lines 95 through 100 determine which size of pizza was selected, and calculates the total price
of the pizza, using the get() method to check the value returned by the Radiobutton group
and calculate the price based on each size group.
Lines 102 through 104 display the total price, rounding the floating point value to two decimal
e
places, and converting it into a string value to display in the Entry widget.
at
b) Select a pizza size and the toppings you want on your pizza. Select Calculate Price, and the total
cost should appear in the Total field.
e
ut
ib
tr
is
D
or
e
c) Select the Reset button to ensure the form fields are reset.
at
Summary
In this lesson, you used the Python tkinter library to create graphical windows with Python code.
You defined an Application subclass, created the constructor to define the window, and defined
the widgets that appear inside the window. Finally, you created event handlers to process window
events generated in the window by the program user.
Encourage students to
What type of Python applications benefit from using a graphical window for entering and displaying data?
e
use the social
networking tools A: Applications that require a lot of input from the program user would benefit from graphical windows. A
ut
provided on the CHOICE command line program would need to ask multiple questions to retrieve each data item from the user,
Course screen to follow which could become tedious. In a graphical window, all of the data items are displayed as form fields
up with their peers after
that the user can fill out to submit all at once to the program.
ib
the course is completed
for further discussion Will your own Python applications typically provide a graphical user interface, command-line interface, or
and resources to support browser-based (web) interface?
tr
continued learning.
A: This will vary depending on your users and requirements. Python supports a wide range of
development needs and can be used to develop any of these types of applications.
is
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
D
peers, and the larger CHOICE online community about the topics covered in this course or
other topics you are interested in. From the Course screen you can also access available
resources for a more continuous learning experience.
or
e
at
lic
up
D
ot
N
o
D
e
Lesson Time: 3 hours, 15 minutes
ut
ib
tr
Lesson Objectives
is
In this lesson, you will:
D
• Identify different ways to store data in a Python program.
• Incorporate an SQLite database in Python programs.
or
• Define basic SQL statements and how to use them.
Lesson Introduction
e
at
As you write larger Python® applications, you'll find at some point that you'll need to store
and retrieve data. Python supports different types of databases, which makes storing and
retrieving data a breeze.
lic
up
D
ot
N
o
D
60 | Python® Programming: Advanced
TOPIC A
Basics of Data Management
Storing data for long-term use in a Python program is a necessity for most applications. Fortunately,
the Python language has several libraries of functions that help with that.
e
You may want show the
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
ut
from the CHOICE course screen.
Course screen or have
students navigate out to
ib
the Course screen and Files
watch them as a
supplement to your In some cases, it makes sense to save data in a local file. This provides the benefit of keeping data in
tr
instruction. If not, please a form that is easy to copy and share (by sharing the file that contains the data). File-based storage
remind students to visit continues to be as relevant and pervasive today as it was decades ago. Some of the most popular
the Spotlights for this
is
software applications, such as Microsoft® Office, use this approach.
course on their CHOICE
Course screen after Python has built-in functions for handling all of your file storage needs. Before you can do any
D
class for supplemental reading or writing of data in a file, your program must first open the file. You use the open()
information and function to open a file:
additional resources.
myfile = open(‘textfile.txt’, ‘mode’)
Files
or
The first parameter specifies the file to open, and the second parameter specifies the mode to open
it in. The mode defines the privileges the program has for interacting with the data file. There are
four different modes.
e
Mode Description
at
r Read-only access.
w Write-only access. The file specified is replaced if it already exists.
lic
The open() function returns a special value called a file pointer. After you open the file, you can use
the file pointer to reference the opened file in any read or write operations.
D
Python writes the specified data directly to the file at the location of the file pointer.
Reading data from a file is a little trickier. There are two ways to read data from a flat file. The
read() method allows you to specify how many characters to read from the file:
N
test = myfile.read(4)
This returns the first four characters in the file. Working your way through a file character-by-
o
character can be somewhat challenging. To make life easier, Python also includes the readline()
function. The readline() function reads the file one line at a time:
D
test = myfile.readline()
This is an excellent way to process text files.
When the file pointer gets to the end of the file, both the read() and readline() functions return
a NULL value, letting you know that there's no more data.
When you're done using the file, you should close the file pointer by using the close() function:
myfile.close()
Database
The downside to simple file-based storage is that it's hard to search for specific data. You have to Database
read each line one-by-one and check the data to find what you're looking for. For applications that
need to do a lot of searching for data, this can become slow and tedious. This is where databases
come in.
e
A database stores data in a file, but uses a separate database engine program that interfaces with the
data file to do all the hard work of reading, writing, and looking for data for you. All your program
ut
needs to do is tell the database engine what you're looking for, and the database engine does the rest.
Python supports many different database engines. The following are some of the more popular
ib
ones.
Database Description
tr
Microsoft® SQL The commercial Microsoft database server that supports medium-to-
Server®
is
large database applications.
Oracle® A commercial database commonly used in Unix® environments.
D
MySQL™ A popular open source database commonly used in websites.
PostgreSQL® A popular open source database that incorporates advanced database
features.
or
For simple database applications, though, Python also supports the SQLite database engine. SQLite
(now called SQLite3 for the current version) is a lightweight engine that runs as a Python library
e
behind the scenes in your application. It’s great for applications that just need a simple local
database to store application data.
at
The key to using a database is the ability to submit simple commands to the database engine, and
receive the results. Most modern databases support a common Structured Query Language (SQL)
lic
for doing just that. The SQL standard defines simple text commands that clients can submit to a
database server to create databases and tables, insert data, and query data values.
up
into tables.
Data fields define the individual data elements in an application. Items such as your name, age,
ot
address, and phone number are stored in the database as data fields.
Each data field is created using a specific data type. The data type defines how the data is stored in
the database. The following are common data types.
N
Guidelines for Creating The first part of any project that uses data should be to design the database tables that are required.
Tables There are some steps that you should take with that process:
• Determine the different data elements required for the application.
e
• Divide the data elements into common groups (called data normalization).
• Determine the data type required to store each data element.
ut
• Determine a primary key for each table.
• Create a separate database for each application.
ib
• Create the tables and data fields.
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 3-1
Designing a Database for Python Pizza
Scenario
e
Instead of storing the toppings list and prices inside the Python Pizza Calculator program code,
ut
you decide it's better to use a separate database to store the values. That way, you can just modify
the database records whenever there are price changes, instead of having to recode the application.
You decide on using the SQLite3 database engine to create a database to store the list of toppings
ib
and the prices for the different pizza sizes and toppings.
Activity: Designing a
Database for Python
tr
1. What data elements will be needed in the database? Pizza
For this activity, consider
is
A: For the Python Pizza Calculator, three data elements will be needed: the list of toppings, the pizza
price for each size, and the price for toppings for each pizza size. having students work in
groups and reconvene
with the entire class to
D
2. What groups of common data will be needed to contain the data elements?
discuss their
A: The data normalization process can be somewhat subjective and tricky. First, determine the conclusions.
common groups for the data. While there may be various ways of doing this, for the Python Pizza
A: For the toppings group, you'll just have the topping data element. For the prices group, you'll need
e
to specify the price, and what the price is for (the product). That makes for two data elements—the
product and the price.
at
A: Again, there is some flexibility here, but in the next activity, you'll store the topping name as a text
value using the varchar data type. Since the topping names aren't too long, you'll use a 15-
character data constraint. For the product data field, you'll store the pizza size and topping size as
a text value, again using the varchar data type. You'll also use the 15-character data constraint
up
for this data field. For the price data field, you'll need to store the product price as a dollar amount,
including two decimal places for the cents. You'll use the decimal data type to do that.
D
ot
N
o
D
TOPIC B
Use SQLite Databases
SQLite databases provide simple database features for an application without requiring an external
database server. The SQLite database engine runs using libraries included with your Python program
and uses a single database file that can be included with your application.
e
ut
SQLite3
SQLite3 SQLite3 provides a lightweight SQL database engine. It does not require a separate server process.
ib
It provides your Python programs with the ability to use common SQL commands to read and write
data to an ordinary data file that works like a database, providing multiple tables, indexes, triggers,
tr
and views. The database file format is cross-platform, which means you can freely copy a database
between 32-bit and 64-bit systems with different architectures. Because SQLite holds an entire
database in one file, you can use an SQLite database like an application file (for document sharing or
is
data transfer) or like a database (which stays on one computer, in one storage location).
While SQLite database files aren't inherently secure, there are numerous ways to improve their
D
security. For example, you can use the third-party library pysqlcipher to encrypt data stored in a
SQLite3 database file. Also, while the examples in this course are relatively simple, when you write
code to access SQLite databases (particularly when you'll have end users other than yourself), be
or
sure to include try...except handlers in your code, since there are many opportunities for things
to go awry when accessing a database file.
e
SQLite3 Database Methods
at
SQLite3 Database The SQLite database engine runs behind the scenes as needed when the Python program attempts
Methods to interact with the database. To use the SQLite methods, you must first import the sqlite3
lic
package:
import sqlite3
After you import the package, to initialize the database, you use the connect() method, specifying
up
the database. After connecting to the database, you need to instantiate a cursor. A cursor is a pointer
that keeps track of your place in the database file. The cursor is required for all interactions with the
database. To generate a cursor, you use the cursor() method:
ot
cursor = conn.cursor()
Notice that the cursor() method is run from the database instance returned by the connect()
N
method. To submit SQL statements to the database, use the execute() method:
cursor.execute(“SELECT * From prices”)
o
Note that the SQL statement is submitted as a string value. The SQLite3 database supports
transactions, which enable you to bundle multiple SQL statements together for processing. If any one
D
of the statements fail, the other statements are rolled back to place the database in its original state.
To submit the transaction, you must use the commit() function, which is part of the connection:
conn.commit()
Finally, when you’re finished using the database, you should close out the connection handle, which
signals the SQLite3 database engine to close the database file:
conn.close()
Database Construction
To build your application database, you’ll need to use the SQL CREATE statement. The CREATE Database Construction
TABLE statement allows you to specify the data fields as well as the data field properties that are used
in the table:
CREATE TABLE prices (product varchar(15) primary key, price decimal)
Each data field is defined within the parentheses in the order that you want them to appear in the
table. You must specify a data type for each data field. This is called a data constraint. The SQLite
e
engine will enforce all data constraints applied to data fields (for example, the varchar(15)
constraint restricts the data to only 15 characters).
ut
The PRIMARY KEY keyword is used to define the data field that will uniquely identify each data
record in the table. The SQLite3 engine will restrict new data records to ensure no two data records
ib
have the same primary key value.
After you create the table, you can insert new data using the INSERT statement:
tr
INSERT INTO prices (product, price) VALUES (‘medium’, 9.99)
The INSERT statement specifies the table to insert the data into, the data fields that are assigned
is
values, and the values assigned to each of the data fields. You use the execute() method to submit
the INSERT statement to the database. However, the INSERT statement doesn’t take effect in the
database until you also submit the commit() method:
D
sql = "INSERT INTO prices (product,price) VALUES('medium', 9.99)"
cursor.execute(sql)
conn.commit()
or
The SQLite database also supports the executemany() method. This allows you to place multiple
data values into a list, and then submit all of the data values as a single entry:
e
sql = ("INSERT INTO prices (product, price) VALUES (?, ?)")
prices = [('medium', '9.99'), ('large', '12.99'), ('x-large', '14.99')]
at
cursor.executemany(sql, prices)
The question marks in the INSERT string are replaced by each tuple value for each iteration in the
lic
list. This is the preferred method of inserting data into tables, as it helps filter out any issues with the
data.
up
conn = sqlite3.connect("mydatabase.db")
Use the execute() method to submit individual SQL statements, or the executemany() to submit
groups of INSERT statements:
cur.execute("CREATE TABLE test (name varchar(15) primary key, age int)")
conn.commit()
e
Follow these guidelines when querying an SQLite3 database.
ut
Build the SELECT Statement
Create the SQL SELECT statement required to retrieve the data that you're interested in:
ib
sql = "SELECT product, price FROM prices WHERE price > 2.00"
tr
Submit the SELECT Statement
Use the SQLite execute() statement to submit the SELECT query to the database:
is
result = cur.execute(sql)
D
Retrieve the Query Results
Use the for statement to retrieve all of the data records in the query result set:
for row in result:
print("Product row[0] costs row[1].")
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 3-2
Building a Database
Data Files
e
All project files in Desktop\AdvPython\Using Databases\PizzaCalculator
ut
Activity: Building a
Scenario Database
You will write a script that will create the SQLite database file that holds the toppings and prices
ib
used for the Python Pizza Calculator. The database will:
• Be stored in a file named pizza.db.
tr
• Include two tables:
• The toppings table, which contains:
is
• The topping field
• The prices table, which contains:
D
• The product field
• The price field
c) In the top-left corner of the Select Path dialog box. select the Home Directory button to select
your user directory.
lic
d) Under your user name, select the triangle next to the Desktop directory to show subdirectories
beneath it.
e) Beneath the Desktop directory, select the triangle next to the AdvPython directory to show
subdirectories beneath it.
up
f) Beneath the AdvPython directory, select the triangle next to the Using Databases directory to show
items beneath it.
g) Beneath the Using Databases directory, select the PizzaCalculator project, and select OK.
D
h) On the left side of the PyCharm window, in the Project window, verify that PizzaCalculator is listed.
e
ut
These statements:
• Import the SQLite3 library.
ib
• Use the connect() method to connect to the database.
• Use the cursor() method to create a cursor object to point to the database connection.
tr
4. Create the toppings and prices tables.
is
a) In create-database.py, write the statements that create the toppings and prices tables.
If you would prefer that
you or your students not
D
type the code in step 4a,
you can copy it from
SNIPPET 2, provided in
Snippets.txt.
SNIPPET 3, provided in
Snippets.txt.
up
D
ot
These statements:
• Create a tuple value that contains the INSERT statement template for the toppings data.
N
• Create a list of tuple values that contain the data values for the toppings.
• Add an executemany() method to add the toppings data.
o
a) In create-database.py, write the statements that insert data into the prices table.
If you would prefer that
you or your students not
type the code in step 6a,
you can copy it from
SNIPPET 4, provided in
Snippets.txt.
e
ut
ib
These statements:
tr
• Create a tuple value that contains the INSERT statement template for the prices data.
• Create a list of tuple values that contain the product and price data.
is
• Add an executemany() statement to add the prices data.
D
If you would prefer that
you or your students not
e
ut
ib
Point out that students Unfortunately, you can't open it directly, as it's a binary-formatted file.
will test the database file
in the next activity.
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 3-3
Using a Database
e
The PizzaCalculator project is open in PyCharm. You have created the pizza.db database file.
ut
Activity: Using a
Scenario Database
You will create a price lookup tool that will read the database and populate a table that shows the
ib
pizza sizes, the price of each size, and the price for toppings at each size.
tr
1. Create the look-up-prices.py script in the PizzaCalculator project.
is
a) In the left window, right-click on the PizzaCalculator project name.
b) From the menu, select New→Python file.
c) In the Name text box, type look-up-prices
D
d) Select the OK button to create the file.
2. Create the template code to build a window and import the tkinter and sqlite3 libraries.
a) Add the following code to the look-up-prices.py script.
or If you would prefer that
you or your students not
e
type the code in step 2a,
you can copy it from
at
SNIPPET 6, provided in
Snippets.txt.
lic
up
D
ot
N
These statements:
• Import the tkinter library and the sqlite3 library.
• Define the Application class and the constructor method.
o
• Instantiate the Tk() object, set the window title and size, instantiate the Application class,
and run the mainloop() method.
D
3. In the Application constructor method, add code to read the prices from the pizza.db database file,
and create the widgets method.
e
ut
ib
tr
is
D
These statements:
• Connect to the database and create the cursor.
•
•
•
or
Create the prices dictionary object—for now, just setting the prices to all 0 values.
Submit a SELECT statement to retrieve the prices from the prices table, placing the values in the
prices dictionary.
Close the database connection using the close() method.
e
• Call the create_widgets() method, which you haven't provided yet.
at
These statements:
• Create the create_widgets() method.
• Create headings for the table.
b) After the headings, but before the instantiation code, add the following code.
If you would prefer that
you or your students not
type the code in step 4b,
you can copy it from
SNIPPET 9, provided in
Snippets.txt.
e
ut
ib
tr
is
D
or
e
at
lic
These statements:
• Create three rows, one for each pizza size.
• Create three columns, one for the label, one for the pizza size price, and one for the topping size
up
price.
• Create the fields to display the prices for each pizza size and topping.
a) Run look-up-prices.py.
e
ut
ib
tr
The window shows the base price for each pizza size and the price for each topping at that size.
The prices have been read from the database.
is
D
or
e
at
lic
up
D
ot
N
o
D
TOPIC C
Manipulate SQL Data
Often, for applications that use databases, the SQL required to interact with the data can get more
complicated than the actual Python code that uses the data. It helps to know the basics of SQL to
help with the database interaction.
e
ut
Database Queries
The SQL SELECT statement is used to submit data queries to the SQLite database engine. The Database Queries
ib
database engine processes the query and returns a result set. The result set contains all of the data
records in the table that match the query criteria. The format of the SELECT statement is:
tr
SELECT fields list FROM table WHERE criteria
The WHERE clause is what limits what data records are returned:
is
SELECT product, price FROM prices WHERE price > 1.00
You then submit the query to the database using the execute() method.
D
The execute() method returns the result set generated by the SELECT statement as a list of values.
The list matches the table data field order. You can iterate through the result set using a standard
for statement:
for row in cursor.execute("SELECT product,price FROM prices"):
prices[row[0]] = row[1]
or
e
For each iteration, the product data field value is assigned to the row[0] list variable, and the price
data field value is assigned to the row[1] list variable.
at
Insert Data
To insert data into a table, write an INSERT statement that provides two pieces of information: the
list of data fields that are updated with values, and the values themselves:
D
• If you provide data values for all of the data fields, you can omit the data field list from the
INSERT statement. The VALUES clause defines the data values that are assigned to the data fields.
N
Query Data
Query Data
To query data, write a SQL SELECT statement, using the WHERE clause to specify the data you want
o
to look for:
D
SELECT product, price FROM products WHERE price < 10.00 ORDER BY product
DESC
• For large result sets, page through the data records using the LIMIT clause:
SELECT product, price FROM products WHERE price < 10.00 ORDER BY product
LIMIT 0,5
• Specify where to start by providing an offset in the first value following the LIMIT clause. The
second value specifies the number of data records to return. In this example, you request the first
five data records in the result set. To request the second five, you'd use:
e
SELECT product, price FROM products WHERE price < 10.00 ORDER BY product
LIMIT 5,5
ut
Update and Delete Data
Update and Delete Data
ib
To update and delete data, use the UPDATE statement. The UPDATE statement also uses a WHERE
clause to specify which data records to update:
tr
UPDATE products SET price = 2.00 WHERE product = 'medium pizza'
• The SET clause is only applied to the data records that match the WHERE clause.
is
• If you need to remove any data records from the database, you use the DELETE statement. Just as
with the UPDATE statement, the DELETE statement uses the WHERE clause to specify just which
D
data records to remove:
DELETE FROM products WHERE product = 'medium pizza'
• Be careful with the DELETE statement; without the WHERE clause, all of the data records from the
table will be deleted without asking.
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 3-4
Changing Data in a Database
e
The PizzaCalculator project is open in PyCharm. You have created the pizza.db database file and
ut
the look-up-prices.py script.
Activity: Changing Data
Scenario in a Database
ib
You will create a new script to update the prices stored in the pizza.db database file. In look-up-
prices.py, you have already created a table that displays the current pricing scheme. By adding an
tr
Update prices button and some more code to update the database, you can create a new script that
enables the user to update the data. So, you will start by creating a copy of look-up-prices.py.
is
1. Copy the look-up-prices.py file to update-database.py.
D
a) If it is not already open in the PyCharm editor, open the look-up-prices.py file.
b) From the main PyCharm menu bar, select File→Save As.
c) In the Copy dialog box, change the file name to update-database.py then select the OK button.
d)
or
In the PyCharm editor window, ensure that the update-database.py file is open and that it is the
active document to edit.
e
2. Leave the database connection open so you can update the data.
a) Remove the conn.close() method from line 22 in the code.
at
lic
up
D
You won't close the database here, as you'll need to update it later on.
ot
3. Add widgets that will enable the user to submit the update.
N
o
D
a) At the end of the create_widgets() method, but before the window instantiation line, add the
code shown.
If you would prefer that
you or your students not
type the code in step 3a,
you can copy it from
SNIPPET 10, provided
in Snippets.txt.
e
ut
ib
These statements provide:
tr
• A blank row.
• A button to submit the updated data using the self.update method.
is
• An Entry field to display the status.
D
4. Add the update() method to update the prices table with the values from the form field.
a) After the create_widgets() method, but before the window instantiation line, add the following
code.
If you would prefer that
you or your students not
type the code in step 4a,
you can copy it from
or
e
SNIPPET 11, provided
in Snippets.txt.
at
lic
These lines:
up
e
ut
ib
tr
is
These lines:
• Use a for loop to iterate through the prices dictionary and submit an UPDATE statement for each
dictionary element, updating the corresponding entry in the prices table.
D
• Call the commit() method after the for loop to commit the updates.
• Display the "Updated" message in the self.entry4 Entry box.
c) To verify the database was changed, select the X at the top-right corner of the window to close the
program, then re-run the program and verify the updated values are there.
d) Close the Python Pizza Prices window to return to PyCharm.
o
e) Close all editor tabs, but leave the PizzaCalculator project loaded in PyCharm.
D
ACTIVITY 3-5
Add a Database to the Python Pizza Application
e
The PizzaCalculator project is open in PyCharm. You have created the pizza.db database file, the
ut
look-up-prices.py script, and the update-database.py script. You have updated the prices in the
database.
Activity: Add a Database
ib
to the Python Pizza Scenario
Application
You will now enable the Python Pizza Application to read data from the database.
tr
is
1. Copy the ppc.py file to ppc-database.py.
a) Open the ppc.py file in the editor.
b) From the main PyCharm menu bar, select File→Save As.
D
c) In the Copy dialog box, change the file name to ppc-database.py then select the OK button.
d) In the PyCharm editor window, ensure that the ppc-database.py file is open, and that it is the active
document to edit.
or
2. Update the constructor to read the price data from the database.
a) Change the toppings list to an empty list, and define the prices dictionary to all 0 values.
e
at
lic
up
D
ot
N
o
D
b) Following the statements you just revised, add code to connect to the pizza.db database.
If you would prefer that
you or your students not
type the code in step 2b,
you can copy it from
SNIPPET 13, provided
in Snippets.txt.
e
ut
ib
tr
These statements:
is
• Connect to the pizza.db database.
• Create a cursor object.
D
c) Following the code you just entered, add code to query the database for topping and price data.
If you would prefer that
you or your students not
This code:
• Uses a for statement to execute a SELECT statement to retrieve the toppings table entries and
D
e
ut
ib
tr
is
D
or
e
The toppings are now in alphabetical order due to the ORDER BY clause added to the SELECT
at
statement.
b) Select a Large pizza with Pepperoni, and select Calculate Price.
lic
5. Update the prices and view the result in the price calculator.
a) Run the ppc-database.py program.
b) Select a Large pizza with Pepperoni, and select Calculate Price.
The new total is 14.19, based on the updated prices in the database.
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
Summary
In this lesson, you used an SQLite database to store, retrieve, and update data that persists between
sessions. You used SQL to create and structure a database, populate it with data values, and perform
queries to retrieve data.
Encourage students to
use the social What sorts of databases will your own Python applications interact with?
e
networking tools A: Answers will vary depending on your requirements, but a wide range of database options exist for
provided on the CHOICE Python developers. Not only are traditional SQL databases an option, but many cloud-based
ut
Course screen to follow database options are now available, including high-performance NoSQL databases that enable you to
up with their peers after
work with massive data sets.
the course is completed
ib
for further discussion Will your own Python applications use data storage options other than databases?
and resources to support
continued learning. A: While databases meet a wide range of needs, other storage options, such as files (XML and JSON, for
tr
example) may be more suitable for some scenarios.
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
is
peers, and the larger CHOICE online community about the topics covered in this course or
other topics you are interested in. From the Course screen you can also access available
D
resources for a more continuous learning experience.
or
e
at
lic
up
D
ot
N
o
D
e
Lesson Time: 2 hours, 15 minutes
ut
ib
tr
Lesson Objectives
is
In this lesson, you will:
D
• Define the different ways to transfer data between applications on a network.
• Design a client-server network application.
Lesson Introduction or
e
These days, just about every computer is connected to some type of network—whether it’s
a simple home network or a complex corporate network with dozens of subnetworks.
at
Python® enables you to leverage the network connectivity of your workstations to allow
them to communicate with each other across the network. This lesson shows how to do just
lic
that.
up
D
ot
N
o
D
86 | Python® Programming: Advanced
TOPIC A
Basics of Network Programming
Before you start coding, it helps to have a basic understanding of how devices communicate across a
network, and what things you need to know to maximize your network connectivity.
e
You may want show the
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
ut
from the CHOICE course screen.
Course screen or have
students navigate out to
ib
the Course screen and Connectionless vs. Connection-Oriented
watch them as a
supplement to your The Internet Protocol (IP) standard has become the de facto method of sending data on Local Area
tr
instruction. If not, please Networks (LANs). The IP standard defines how data packets are sent from one device to another
remind students to visit across multiple networks. However, by itself, the IP standard doesn’t define just how that data is
the Spotlights for this
is
processed at the application level.
course on their CHOICE
Course screen after For applications to communicate with each other, a finer control of the data is required. Two
D
class for supplemental popular standards have been built on top of the IP standard that define different methods for
information and moving data between network devices.
additional resources.
Connectionless vs.
Connection-Oriented
Item
Transmission Control
Protocol (TCP)
Description
or
TCP defines a detailed protocol for sending data error-free between two
network devices, ensuring that all data that is sent on one end is received
e
intact on the other end.
The receiving device must acknowledge receipt of each byte of data sent
at
by the sending device, and the sending device can’t send more data than
the receiving device can handle. These rules ensure that whatever data is
lic
User Datagram To avoid the performance issues of TCP, UDP does not track data the
Protocol (UDP) way TCP does. The sending device sends out a packet of data to the
receiving device, and has no idea if the packet made it to the destination,
ot
or if the destination device was able to process it. While this method can
produce lots of dropped packets, it's much faster in transferring data, as
there’s much less overhead. Most real-time audio and video streaming
N
TCP is described as providing connection-oriented data transfer, whereas UDP provides connectionless
o
data transfer.
D
Client/Server Paradigm
Client/Server Paradigm After you decide on a network protocol to use, you must decide on how the network devices will
use that protocol to communicate with each other. Both network devices in a connection can’t talk
at the same time. One must be listening for incoming data at the same time the other device sends it.
That means the two devices must agree on a protocol to establish when to send data and when to
listen for data. The most popular protocol method used is the client/server paradigm. With this
paradigm, one side of the connection assumes control over the communication channel. The server
side always listens for incoming connections from clients. The client sends a connection request to
the server, and the server must accept it before communication can begin. Once the connection is
established, the client sends a command to the server, and the server processes the command, then
returns any data requested. This method is used in most popular IP protocols, such as Hypertext
Transfer Protocol (HTTP), File Transfer Protocol (FTP), and Simple Mail Transfer Protocol
(SMTP).
e
In most server environments, there are multiple server programs that listen for connections on the
ut
same network interface. The way the physical server knows which incoming packet goes to which
server program is by using ports. A port is a number assigned to each server program listening for
incoming packets. The client must know the unique port number for the server it wants to
ib
communicate with. Each application server is assigned its own unique port number for the physical
server. All standard Internet protocols are assigned well-known port numbers (such as port 80 for
HTTP, port 21 for FTP, or port 25 for SMTP). You shouldn't use an existing well-known port
tr
number for your application, but usually any port number over 1024 is fair game.
is
Guidelines for Basic Network Programming
D
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
CHOICE Course screen.
ACTIVITY 4-1
Defining an Application Protocol for the Python
Pizza Calculator
e
Scenario
ut
You are going to turn the Python Pizza Calculator into a client-server application. The server will
provide the latest pricing information to each instance of the client application. The server will run
ib
on one computer, and instances of the client will run on other computers that connect to the server
over a LAN. Before you start, you'll need to work out some networking details.
Activity: Defining an
tr
Application Protocol for
the Python Pizza 1. What connection protocol and port will you use for the application?
is
Calculator
A: Since the Python Pizza Calculator needs to accurately send topping and price data across the
Discuss these questions network, TCP is an appropriate choice. Regarding the port, many numbers are available and
with the entire class or
D
appropriate. (In the activity, you'll use port 8000.)
consider dividing
students into teams.
2. You will modify the Python Pizza Calculator to be either the client application or the server application.
Which one should it be?
or
A: Since customers will run the Python Pizza Calculator window, you'll use that as the client device.
You'll create a separate server program to serve the toppings list and prices dictionary values.
The server will listen on TCP port 8000 and the client (the Python Pizza Calculator window) will
e
request a connection to the server program.
at
A: In addition to opening to a new connection, the server must be able to provide toppings, prices, or
terminate the connection (exit). The client will send these as text commands to the server. The
server will return data in response to received client commands. If the server receives a topping
command, it will send the toppings list. If the server receives a prices command, it will send the
D
prices dictionary object. Finally, if the server receives an exit command, it will terminate the
connection with the client.
ot
N
o
D
TOPIC B
Create a Client/Server Program
You've planned the functionality of your client-server application. Now, you will use Python's
socket library to provide communication between a client and server application over a network.
e
Python Socket Library
ut
The Python socket library contains methods for both the client and server programs to interface Socket
with the network card and each other. To use the socket library, you’ll need to import it into your The examples covered
ib
Python script: in this course are
import socket intended to provide a
straightforward
tr
The socket library contains lots of different methods to assist you in your network programming. introduction to network
Here are the most common methods that you’ll use. programming in Python.
is
Point out that it is also
Method Description possible to implement
asynchronous
D
accept() Accepts an incoming connection attempt. communication through
the Standard Library,
bind(address) Binds the socket to an address and port. and that third-party
close()
connect(address)
or
Closes an established connection.
Establishes a connection with a server.
Returns the IP address of the specified host name.
modules, such as
twisted matrix, may help
to simplify complex
network communication
e
gethostbyname(host) tasks.
gethostname() Returns the host name of the local system.
at
Server
ot
With so many methods available, at first, it may seem somewhat complex to use the socket library. Server
However, there's a set process for both the server and client sides of the connection, so coding them
is a snap.
N
For the server, you most often use this sequence of methods:
import socket
o
port= 8000
server.bind(host, port)
server.listen(5)
The socket() method parameters are somewhat complex, but they’re also somewhat standard. The
first parameter defines the protocol family (AF_NET requests to use IP), and the second parameter
defines the lower-level protocol (SOCK_STREAM is for TCP connections, and SOCK_DGRAM
for UDP).
The bind() method establishes the program’s link to the socket. It requires a tuple value that
represents the host address and port number on which to listen. If you bind to an empty host
address, the server listens on all IP addresses assigned to the system. If you need to listen on only a
specific network interface address, you can specify the specific hostname or IP address for the
interface.
After you bind the socket, you use the listen() method to start listening for client connections.
The program halts at this point, until it receives a connection request from a client. When a
connection attempt is received, you pass it to the accept() method:
e
client, addr = server.accept()
This is somewhat of an odd format. The two variables are required because the accept() method
ut
returns two data values. The first is a handle that identifies the connection to the client, and the
second is the address of the remote client.
ib
After the connection is established, you use the send() and recv() methods to send data with the
client. When the communication is complete, use the close() method to close the connection.
tr
Client
is
Client Once you have a server running, you can start working on the client program. The client side of the
programming is somewhat simpler:
D
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(“localhost”)
port = 8000
s.connect((host, port)) or
The client code uses the gethostbyname() method to find the connection information for the
e
server, based on the server’s hostname. The localhost address points to the same system that the
program is running on.
at
That’s all you need for the client! Once the server accepts the connection, you use the send() and
recv() methods to communicate with the server. When the communication is complete, the client
lic
Data Transmission
up
Data Transmission There’s a caveat to sending and receiving data across a network connection. Different types of
computer hardware systems use different formats for storing data in memory. Because of that, it can
D
be dangerous to send data as text or numeric values from one system to another on the network. To
solve that problem, the network interface converts all data to network byte order.
However, because of that, the socket send() method can only send bytes. That means the data you
ot
place in the send() method parameter must be in byte format instead of a text or numeric format.
Fortunately, Python provides a function that can convert text to bytes with the str.encode()
method:
N
s.send(str.encode(“This is a test”))
On the receiving end of the connection, the recv() method returns the received data in raw byte
o
format. To make any sense out of the data, your program will need to convert it to text format.
Again, Python comes through with the bytes.decode() method:
D
data = s.recv(1024)
string = bytes.decode(data)
This is all you need to send and receive simple text and numeric data across the network.
Serialization
Often, you’ll have more complex data types (objects, such as lists or dictionaries) that you need to Serialization
send between devices. To do that, you need to incorporate a process called serialization. With
serialization, the complex data type is broken down (serialized) into a text item before being sent on
the network. When the data is received on the other end of the connection, the received data is then
converted back into the original data type.
While this sounds complicated, as with everything else, there are Python methods to help you out.
Currently, the most popular method used to serialize complex data types is the JavaScript Object
e
Notation (JSON) data-interchange format. The json Python library implements methods that use
ut
JSON to serialize complex data types and convert them back into the original data type. The
dumps() method serializes the complex data into a text string, and the load() method converts it
back into the complex data type:
ib
output = str.encode(json.dumps(data))
client.send(output)
tr
data = client.recv(1024)
is
text = json.load(bytes.decode(data))
D
The json and socket library methods simplify the process of sending complex data between Guidelines for Handling
devices across any type of network: Data on a Network
• Serialize complex data using the json dumps() method.
• Encode the serialized data using the str.encode() method.
or
• Send the encoded data to the remote host using the socket send() method.
e
• On the other end, receive the data using the socket recv() method.
at
If you intend to transfer sensitive information, be sure to take measures to secure communications. Security
For example:
• Use the Python Transport Layer Security/Secure Sockets Layer (TLS/SSL) wrapper library
D
whitelist), and write the server code to accept connections only from IP addresses in that list.
The server can call socket.getpeername() to determine the client's IP address. Make sure that
the list of acceptable addresses is stored in a secure location that can't be modified by
N
ACTIVITY 4-2
Creating a Server for the Python Pizza
Calculator
e
Data Files
ut
All project files in Desktop\AdvPython\Network Programming\PizzaCalculator
Activity: Creating a
ib
Server for the Python Scenario
Pizza Calculator
You'll create a server program to serve Python Pizza Calculator clients with the current list of
tr
toppings and pizza prices from a central location across the network. The server will use TCP port
8000.
is
1. Launch PyCharm and open the PizzaCalculator project.
D
a) From the desktop, double-click the JetBrains PyCharm Community Edition 3.4 shortcut and select
Open Directory.
b) Navigate to the Desktop\AdvPython\Network Programming directory, select the PizzaCalculator
project, and select OK.
or
c) On the left side of the PyCharm window, in the Project window, verify that PizzaCalculator is listed.
3. Add the required import statements and code to read data from the database.
If you would prefer that a) Add lines to import the libraries that will be used by the server.
up
provided in Snippets.txt.
ot
N
o
D
b) Skip a line after the import statements and add the following statements.
e
ut
ib
tr
is
D
or
e
at
These statements:
• Connect to the pizza.db database using the sqlite3.connect() method (line 7).
• Create a cursor object for the connection (line 8).
lic
• Create an empty toppings list (line 10), then submit the SQL SELECT statement to retrieve the
data from the toppings table and populate the list with the data values (lines 11 and 12).
• Encode the toppings list for network transmission (line 14).
up
• Create the dummy prices dictionary object (lines 15 through 20), then submit the SQL SELECT
statement to retrieve the price data from the prices table and populate the dictionary object with
the data values (lines 22 and 23).
• Encode the prices list for network transmission (line 25).
D
e
ut
ib
These statements:
• Create a socket object on port 8000.
tr
• Bind to all interfaces on the local workstation.
• Listen to incoming connections on TCP port 8000.
b) Create a while loop to listen for connections.
is
If you would prefer that
you or your students not
D
type the code in step 4b,
you can copy it from
SNIPPET 3, provided in
Snippets.txt.
or
e
at
lic
The while loop accepts incoming connections from clients and sends the welcome message. This
will loop continually. Next, you need to add code to listen for various commands, including one to
break out of the loop and close the connection.
up
D
ot
N
o
D
e
ut
ib
tr
is
D
These statements:
• Continually loop, listening for messages from the client. or
• Send the toppings list if the client sends the toppings command (lines 43 through 45).
e
• Send the prices list if the client sends the prices command (lines 46 through 48).
• Break out of the loop if the client sends the exit command.
at
This statement, which closes the connection with the client, is reached only when the exit
command causes a break in the inner loop.
ot
a) Run ppc-server.py.
Note: At some point, you may be prompted by your local firewall service to
allow the application to communicate over the network. If this happens, select
the option to allow it.
In the console window, you will see output from the server. For now, all you'll see is the Listening for
a client output.
e
ut
ib
tr
is
D
6. Stop the server program.
a) In the left side of the console area, select the red square icon to stop the program.
b) Press Ctrl+F4 to close the console.
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 4-3
Adding Network Features to the Python Pizza
Calculator
e
Before You Begin
ut
The PizzaCalculator project is open in PyCharm.
Activity: Adding Network
ib
Scenario Features to the Python
Pizza Calculator
You're ready to connect the Python Pizza Calculator client application to the server to retrieve the
tr
toppings list and prices dictionary.
is
1. Copy the ppc.py file to ppc-client.py.
a) If it is not already open in the PyCharm editor, open the ppc.py file by double-clicking its entry in the
D
project file list on the left side of the window.
b) From the main PyCharm menu bar, select File→Save As.
c) In the Copy dialog box, change the file name to ppc-client.py and then select the OK button.
document to edit.
b) Change the toppings list to an empty list, and define the prices dictionary to all 0 values.
D
ot
N
o
D
3. Add code to connect to the ppc-server program and receive the welcome message.
a) After the statement that initializes self.prices, insert a new line and add code to connect to the server
and receive the welcome message.
If you would prefer that
you or your students not
type the code in step 3a,
you can copy it from
SNIPPET 5, provided in
Snippets.txt.
e
ut
ib
tr
is
D
These statements:
• Establish a socket connection on localhost, port 8000.
or
• Receive the welcome message in a buffer variable named data.
b) After the code you just added, add code to send the toppings command to the server, retrieve the
data, and place it in the toppings list object.
e
If you would prefer that
you or your students not
at
Snippets.txt.
up
D
ot
These statements:
• Encode the text "toppings" using the str.encode() method, and send it using the socket
N
send() method.
• Retrieve the result using the socket recv() method.
• Use the bytes.decode() method to convert it into a string value.
o
• Load the JSON format using the json loads() method to create the toppings list.
D
c) After the code you just added, add code to send the prices command to the server, retrieve the
data, and place it in the prices dictionary object.
If you would prefer that
you or your students not
type the code in step 3c,
you can copy it from
SNIPPET 7, provided in
Snippets.txt.
e
ut
ib
tr
is
These statements:
D
• Encode the text "prices" using the str.encode() method, and send it using the socket send()
method.
• Retrieve the result using the socket recv() method.
•
• or
Use the bytes.decode() method to convert it into a string value.
Load the JSON format using the json loads() method to create the prices dictionary object.
4. After the code you just added, add code to send the exit command to the server.
e
If you would prefer that
at
SNIPPET 8, provided in
Snippets.txt.
up
D
ot
b) In the PyCharm window, observe the console output, showing that the server is listening for client
connections.
e
ut
ib
6. Run the ppc-client program.
tr
a) Run the ppc-client.py script.
b) The Python Pizza Calculator window should appear, with the list of toppings. Select a size and some
is
toppings, then select the Calculate Price button.
D
or
e
at
lic
up
D
ot
N
7. In the console window, select the ppc-server tab and view the server output.
o
D
e
ut
ib
8. Clean up the workspace.
a) In the left side of the console area, select the red square icon to stop the server.
tr
b) In the upper-right corner of the client application window, select the X to stop the client program.
c) Select a console window and press Ctrl+F4 twice to close the console windows.
is
d) Select File→Close Project to close the project.
e) Close the PyCharm Community Edition window to exit PyCharm.
D
or
e
at
lic
up
D
ot
N
o
D
Summary
In this lesson, you used the socket library to implement a client-server connection between two
Python applications.
Encourage students to
use the social In your own Python applications, will you have a need to develop client-server applications?
networking tools A: Answers will vary. For some developers, this is a primary reason why they use Python. However you
e
provided on the CHOICE may develop applications that are completely self-contained and require no network connections. In
Course screen to follow other classes, your applications may use cloud services, and you may be more likely to use a library
ut
up with their peers after
other than socket to access web or cloud services.
the course is completed
for further discussion What measures might you need to take if your client-server application transmitted sensitive information?
ib
and resources to support
continued learning. A: The Python Pizza Calculator transmits messages as clear text. If you need to transmit sensitive data,
you should consider adding encryption and decryption capabilities on either end of the message.
tr
Using a protocol such as SSL provides a secure connection that authenticates users on each end of
the communication and encrypts data in the communication channel.
is
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
peers, and the larger CHOICE online community about the topics covered in this course or
D
other topics you are interested in. From the Course screen you can also access available
resources for a more continuous learning experience.
or
e
at
lic
up
D
ot
N
o
D
e
ut
Threading
ib
Lesson Time: 2 hours, 30 minutes
tr
is
D
Lesson Objectives
In this lesson, you will: or
• Run multiple operations concurrently in the same process space.
e
• Manage resources accessible to threaded applications.
at
Lesson Introduction
lic
Today’s computing environment of dual-core and quad-core processors provides the ability
to run multiple processes on a system at the same time, helping increase the performance of
up
your applications. You can take advantage of this power by incorporating threading in your
Python® programs.
D
ot
N
o
D
104 | Python® Programming: Advanced
TOPIC A
Create a Threaded Application
You've created an application that may need to run multiple operations simultaneously. You can
implement this capability through threading.
e
You may want show the
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
ut
from the CHOICE course screen.
Course screen or have
students navigate out to
ib
the Course screen and Threading
watch them as a
supplement to your When you run the Python Pizza Calculator server program, you may run into a small problem. If
tr
instruction. If not, please more than one client attempts to query the server at the same time, only one client will be serviced
remind students to visit at a time. That’s because the server program runs as a single process on the system, and can only
the Spotlights for this
is
communicate with one client at a time. In a high-volume multi-user environment, making customers
course on their CHOICE
Course screen after wait in line just won't work. Threading helps solve that problem.
D
class for supplemental Threading enables you to break off separate functions in your program into separate processes
information and running on the system. Instead of the program accepting a client connection and having to wait until
additional resources. the client finishes before accepting another client, your program can use threading to fork the
Threading
client requests.
or
connection to a separate program thread, leaving the original thread available to listen for more
Threading can also be used in programs that require processing of multi-part, complex data. For
example, there may be times when your program needs to calculate several values first, then
e
combine those values into a final calculation. You can fork the calculations into separate threads to
at
run in queued order, then return to the main thread to combine the answers into a final value.
With threading, there's always a main process that initiates the individual threads. A thread is a single
process block on the central processing unit (CPU). Threads that run in the foreground on the
lic
computer system are also called processes, while threads that run in background on the computer
system are called daemons. Daemons can continue to run after the main thread completes. When that
happens, they're called orphans. Orphaned threads can cause problems on a system, so it's best to
up
Thread Objects
D
Thread Objects Python uses the threading library to implement threading in your programs. There is an older
Python library named thread, but it has been deprecated and shouldn’t be used. The threading
ot
library includes the Thread class, which allows you to create separate thread objects in your
programs.
To create a thread object, you just create a subclass of the Thread class:
N
def __init__(self):
threading.Thread.__init__(self)
D
The Thread class includes several methods and properties for working with threads.
Feature Description
daemon Thread property that determines whether the thread runs in background or
foreground.
Feature Description
ident Thread property that uniquely identifies each running thread.
is_alive() Method to determine if the thread is active.
join() Method to allow the main thread to wait until a forked thread terminates.
name Thread property that you can assign to identify the thread.
run() Method that is processed when the thread starts.
e
start() Method used to initialize a thread and execute the run() method.
ut
Guidelines for Python Threading
ib
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
CHOICE Course screen.
tr
Follow these guidelines when working with threads in your Python programs: Guidelines for Python
is
• Import the threading library. Threading
• Create a subclass of the Thread class.
D
• Define the run() method and place the code you want to run in the thread inside the method.
• In the main program, instantiate an instance of the thread subclass.
• Run the start() method for the subclass to start the thread.
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 5-1
Creating a Threaded Application
Scenario
e
Before you add threading capabilities to the Python Pizza Calculator, you want to ensure that you
ut
understand how threading works in Python and the implications of adding it to a program. So, you'll
develop a script that will use threads to calculate the factorial of several numbers, using separate
threads for each calculation. You find the factorial of a number by multiplying the series of numbers
ib
from 1 up to the number. For example, the factorial of 5 is 1 * 2 * 3 * 4 * 5. By logging the results in
the console, you'll be able to test whether the calculations are actually being performed in separate
threads.
tr
Activity: Creating a
Threaded Application
is
1. Launch PyCharm and create a new project.
a) From the desktop, double-click the JetBrains PyCharm Community Edition 3.4 shortcut.
D
b) In the PyCharm Community Edition window, select Create New Project.
c) In the Create New Project dialog box, in the Project name text box, type Factorials
d) Next to the Location field, select the Browse button to open the Select Location for Project Directory
dialog box.
or
e) Navigate to the Desktop\AdvPython\Managing Multiple Processes with Threading directory.
f) Select the Managing Multiple Processes with Threading directory, and select OK to return to the
Create New Project dialog box.
e
A new Factorials subdirectory will be created within the Managing Multiple Processes with
at
Threading directory.
g) Select OK to create the new project.
h) On the left side of the PyCharm window, in the Project window, verify that Factorials is listed.
lic
a) Add the following code to thread-factorial.py to create a Thread subclass and constructor.
If you would prefer that
you or your students not
type the code in step 3a,
you can copy it from
SNIPPET 1, provided in
Snippets.txt.
e
ut
This code:
ib
• Imports the threading library (line 3).
• Defines the myFactorial subclass of the Thread class (line 5).
tr
• Defines the __init__() constructor method. The method takes one parameter—the number to
calculate the factorial.
is
b) Add the factorial function code inside the run() method for the thread subclass.
If you would prefer that
you or your students not
D
type the code in step 3b,
you can copy it from
SNIPPET 2, provided in
or Snippets.txt.
e
The run() method:
at
SNIPPET 4, provided in
Snippets.txt.
D
You don't have to start the threads in the order in which you created them. In this example,
thread3 is started before thread2.
a) Run thread-factorial.py.
e
ut
ib
tr
The output appears in the console area in the editor window. The output shows that all three threads
ran, but your output may not necessarily be in the same output order that the threads were started.
In the example shown here, thread1 (factorial of 10000) completed last, even though it started first.
is
This verifies that the threads function independently and will take as long as needed to complete
their tasks.
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 5-2
Determining the Current Thread
e
You have created the Factorials project, which is open in PyCharm.
ut
Activity: Determining the
Scenario Current Thread
The Thread class includes the name and ident properties to help you identify threads. There's also
ib
the current_thread() method which returns those properties of the current thread. You can
change the name property to any value you like to help identify individual threads. In this activity,
tr
you'll create a thread that counts from 1 to 10 with a varying delay. You'll then initiate two threads
with different thread names and delay times. You'll watch as Python processes the code in the two
is
threads.
D
1. Create the thread-name.py file in the Factorials project.
a) In the left window, right-click on the Factorials project name.
b) From the menu, select New→Python file.
c)
d)
In the Name text box, type thread-name
Select the OK button to create the file. or
e
2. Program the myThread class.
a) Enter the following code.
at
This code:
• Imports the threading and time libraries.
N
• Defines the myThread subclass of the Thread class, along with its constructor, which takes two
parameters—a name for the thread, and the delay time.
o
D
e
ut
• Line 13 calls the current_thread() method to display information about the current thread.
• The loop in line 14 iterates a counter from 1 through 10. (The loop ends as soon as it reaches
11, so the steps are not performed for a value of 11.)
ib
• Line 15 prints the thread's name, identity, and counter value.
• Line 16 uses the delay value in the sleep() method to delay each loop iteration in the thread.
• Line 17 shows a message when the loop completes.
tr
c) Write code to instantiate and start the threads.
is
If you would prefer that
you or your students not
type the code in step 2c,
D
you can copy it from
SNIPPET 7, provided in
Snippets.txt.
or
e
at
• Line 19 prints a message to show that the main thread started running.
lic
• Lines 20 and 21 create two instances of the myThread subclass, each with a different name and
delay value.
• Lines 23 and 24 start the threads.
up
• Line 25 prints a message to show that the main thread has completed.
a) Run thread-name.py.
e
ut
ib
tr
is
D
Note: You may need to scroll or change the height of the output window to see
all of the information logged there.
b) In the output window, observe the following:
•
•
The name of each thread is shown as the thread is started.
or
The current_thread() method shows the thread subclass name (myThread), along with the
e
name assigned to each thread, and its ident value.
• Each line of output identifies the thread name that you assigned, and the unique ident value for
at
the thread.
• Because the first thread has a lower delay value, it completes before the second thread.
lic
up
D
ot
N
o
D
TOPIC B
Manage Thread Resources
When working with threads, you must pay close attention to how the threads interact with system
resources. If two threads attempt to access the same resource at the same time, they will cause a
deadlock condition. Your program must be able to control how the individual threads access data
e
and hardware on the system.
ut
Resource Collisions
ib
Resource Collisions A common use for threads is to break up a complex task into multiple pieces. Each piece performs a
specific section of the task, and reports back to the main program when it completes. However,
tr
sometimes, one thread needs to complete its actions before another thread can continue. You need
a way to specify that in your thread code. This process is called synchronization.
is
Python implements synchronization using the locking feature. Locking allows one thread to place a
hold on the processing while it performs a crucial code segment. While the lock is in place, the
operating system blocks any other threads from running. When the thread is finished with the
D
crucial code, it must release the lock to allow other threads to continue.
Python uses the threading.Lock class to provide the locking feature for your threads. To create a
mylock = threading.Lock() or
lock, first you need to create an instance of the Lock class:
Then inside the thread code, when you need to block other threads, use the acquire() method to
e
start the block:
mylock.acquire()
at
The acquire() method attempts to lock the resource. If the resource is already locked by another
thread, by default, the acquire() method returns a False value and your program must try again
lic
later. If you prefer, you can add a True value as a parameter to the acquire() method to force
your program to wait until the resource is unlocked. Once you acquire the lock, you must release it
when your thread is done processing. You do that using the release() method:
up
mylock.release()
Data Corruption
D
Data Corruption When you use threading in your applications, you must be careful when handling variables. When
the operating system starts your main program, it allocates an area of memory to store the program
ot
variables. Any threads that your program spawns also have access to that same memory area. That
means you could have several separate threads trying to access the same memory areas at the same
time, which could cause problems.
N
To help solve that issue, you can declare variables to be local to a thread (called thread local storage).
The Python threading.local class in the threading library allows you to specify an object that
holds the thread local attributes. To create a thread local storage area in your program, just
o
localdata = threading.local()
Then, you can create attributes to store any thread local data:
localdata.test = 1
localdata.mylist = [1, 2, 3]
You can store any type of data in thread local storage. Any data that you store in the thread local
object can only be accessed by the thread that created it.
e
By default, you can place an unlimited number of items in the queue. If you want to limit the
number of objects in the queue, specify that value as a parameter when you instantiate the Queue()
ut
object.
Once you create the queue, you can place objects into the queue using the put() method:
ib
myqueue.put(“Item1”)
To retrieve an object from the queue, use the get() method:
tr
test = myqueue.get()
By default, the queue works as a first-in-first-out (FIFO) queue. The get() method retrieves values
is
in the same order that the put() method places them in the queue. You can also create a last-in-
first-out (LIFO) queue using the LifoQueue class.
D
There are a handful of useful methods that go along with the Queue class. The empty() and full()
methods are great ways to determine whether the queue is empty or full. The qsize() method will
return how many items are in the queue.
or
With queues, the key is for one thread to place items into the queue and another thread can safely
retrieve them. However, if you have to worry about threads trying to place data in the queue at the
same time, you can also use the locking feature to block other threads.
e
Threading vs. Multiprocessing
at
Threading runs multiple blocks of code within a shared process and memory space. To prevent Threading vs.
lic
collisions between threads trying to access the same data simultaneously, threads must be managed Multiprocessing
by the locking process (known as the Global Interpreter Lock, or GIL), which enables only one
thread to access an object at one time.
up
Multiprocessing runs multiple blocks of code within separate processes and memory space. If the
computer has multiple CPU cores, multiprocessing (unlike threading) can take advantage of them,
running separate processes simultaneously on different CPU cores.
Threading can speed up certain tasks, but not other tasks. Some processing tasks are CPU-bound,
D
meaning they are slowed down waiting for processing to be done by the CPU. Others may be input/
output (I/O)-bound, meaning they are slowed down by input and output tasks, such as accessing
files from a disk, network, and so forth. Because threading runs separate blocks of code in the same
ot
process, it can't speed CPU-bound tasks, but it can speed up I/O-bound tasks.
If a processing bottleneck occurs when data is obtained from sources outside of the computer (for
N
example, data to be downloaded from various web servers), then threading is well-suited for the
task, since the majority of the effort performed by the task is in waiting for external processes to
complete. You can add a thread for each additional download and the data can be downloaded
o
simultaneously through the separate threads. One download does not have to wait for another to
complete before it can start.
D
On the other hand, if the separate tasks to be performed are locally performed, CPU-intensive tasks,
then multiprocessing may be the more appropriate choice, and it may produce much faster
performance.
There are some potential drawbacks to using multiprocessing, however. It is more complicated to
safely share data across processes, for example. Also, it takes more time to start up a new process
than to start a new thread.
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 5-3
Communicating Between Threads
e
You have created the Factorials project, which is open in PyCharm.
ut
Activity: Communicating
Scenario Between Threads
Now you'd like to explore how threads can safely share data using a queue. The main program will
ib
create a list of numbers that need to be processed by the factorial method. The program will load
the list into a queue object, then create a pool of three separate threads to operate on the list. Each
tr
thread will grab the next number from the queue and process it. When the queue is empty, the main
program will signal the threads that they are done and can exit.
is
1. Create the thread-factorial-pool.py file in the Factorials project.
D
a) In the left window, right-click the Factorials project name.
b) From the menu, select New→Python file.
c) In the Name text box, type thread-factorial-pool
d) Select the OK button to create the file.
SNIPPET 8, provided in
Snippets.txt.
up
D
These lines:
• Import the queue and threading libraries.
ot
e
• The class is a subclass of Thread.
ut
• The constructor takes two parameters—a name for the thread, and the queue object to retrieve
the data from.
c) Create the run() method for the calcThread subclass.
ib
If you would prefer that
you or your students not
tr
type the code in step 2c,
you can copy it from
SNIPPET 10, provided
is
in Snippets.txt.
D
or
e
at
• Line 17 displays a message that shows the name of the thread that is starting.
• Line 18 creates a thread local storage object.
lic
• Lines 19 through 27 contain a while loop that terminates based on the value of the terminate
variable.
• If the queue is not empty yet (line 20), then the next value is retrieved from the queue and the
factorial for it is calculated.
up
• When the queue is empty, execution breaks out to line 28, which displays a message that shows
the name of thread that is completing.
3. Finish up the script by instantiating and running three instances of the thread you just defined.
D
ot
N
o
D
e
ut
ib
tr
is
• Lines 30 through 32 instantiate three instances of the calcThread subclass. Each thread has a
different thread name, and the dataQueue object is passed to each one.
D
• Lines 34 and 35 load the numbers from the list into the dataQueue object.
• Lines 37 through 39 start the three threads in the thread pool.
• Lines 41 and 42 run a tight loop that checks the dataQueue object. The loop will be exited when
•
the data queue is empty.
or
When the queue is empty, line 43 sets the terminate variable to True to signal the threads to
exit.
e
• Line 44 displays a message to show that the main thread is finished.
at
Note: Depending on your processor speed and timing of the threads, your
output may not exactly match the output shown here.
b) Determine if all three threads in the thread pool have started.
Depending on how many data values you placed in the queue, and how large the values are, some
threads in the pool may not get used.
c) Examine the console and verify that all threads have exited when the main thread exited.
d) Run the script again, and observe that different threads may process the values, depending on
timing.
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 5-4
Using the Threaded Python Pizza Server
Data Files
e
All project files in Desktop\AdvPython\Managing Multiple Processes with Threading
ut
\PizzaCalculator
Activity: Using the
Before You Begin Threaded Python Pizza
ib
Server
PyCharm is running.
tr
Scenario
Now that you've seen how threading works, you will examine a version of the ppc-server.py
is
program in which threading has already been incorporated. After a client connects to the server, a
separate thread is used to process the communication with the client, so the main thread can go
D
back to listening for more clients.
or
a) In PyCharm, select Open Directory. Navigate to the Desktop\AdvPython\Managing Multiple
Processes with Threading directory, select the PizzaCalculator project, and select OK to open the
project.
e
b) On the left side of the PyCharm window, in the Project window, verify that PizzaCalculator is listed.
at
e
ut
ib
tr
is
D
or
• The class is a subclass of the Threading class.
• The client and address are provided as parameters of the constructor.
e
• Data is read from the database in the same manner as it was read in ppc-server.py.
d) Examine the run() method.
at
lic
up
D
ot
N
o
D
The run() method handles client communication in same manner as it was done in ppc-server.py.
e
ut
ib
• Code to create the server socket is very similar to the code used in ppc-server.py.
tr
• A while loop listens for new client connections, spawning them off to a new clientThread
object in lines 65 and 66, and then continuing to listen for new clients.
is
3. Run the ppc-threaded-server.py program.
D
a) Run ppc-threaded-server.py.
b) Look at the console output to ensure the server is listening for new client connections.
or
e
at
lic
up
5. In the console, select the tab to observe the ppc-threaded-server console output.
ot
N
o
D
e
ut
ib
tr
The server accepted the client connection, but then started listening for more clients before
is
communicating with the connected client.
D
a) Right-click the ppc-client console window tab, and select Close All.
or
e
at
lic
Summary
In this lesson, you used threading to create parallel code threads in your programs.
Encourage students to
In your own applications, will you have a need to implement threading? use the social
A: Answers will vary. In Python, threading is helpful for situations calling for input and output, such as networking tools
downloading and processing web data, or managing network communications. Because of the way provided on the CHOICE
Course screen to follow
e
threading is implemented in Python, some tasks that would benefit from parallel processing, such as
up with their peers after
heavy number-crunching, may actually run slower in threaded applications. Python provides a
ut
the course is completed
multiprocessing module, which is more suitable for running tasks that require true parallel
for further discussion
processing. and resources to support
ib
continued learning.
When implementing threading, are there any factors you'll need to be careful of?
A: One concern that was covered in this lesson is data corruption. When multiple threads access the
tr
same data, it must be accessed in a controlled way.
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
is
peers, and the larger CHOICE online community about the topics covered in this course or
other topics you are interested in. From the Course screen you can also access available
D
resources for a more continuous learning experience.
or
e
at
lic
up
D
ot
N
o
D
e
ut
Lesson Time: 2 hours, 20 minutes
ib
tr
is
Lesson Objectives
D
In this lesson, you will:
Lesson Introduction
lic
Before you release your Python® application to customers, you'll want to ensure that it's
bug-free. The Python Unit Test feature allows you to create a test environment that ensures
your program works as advertised. However, you can also use the unit test feature to set up
up
a test environment before you even write any code for your application. That allows you to
develop the code to match the test environment, ensuring success in the final product.
D
ot
N
o
D
126 | Python® Programming: Advanced
TOPIC A
Test-Driven Development
Test driven development allows you to create a series of tests that define how the application should
behave before you write any code for the application. Once you define the tests, you then write the
code to pass the tests.
e
You may want show the
ut
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
from the CHOICE course screen.
Course screen or have
ib
students navigate out to
the Course screen and Plan for TDD
watch them as a
tr
supplement to your There's nothing worse that working with an application that doesn't work quite right. Being in the
instruction. If not, please middle of an application that produces wrong data, freezes when an event is selected, or
is
remind students to visit unexpectedly crashes creates distrust in your customers, and can lead them to look for an alternative
the Spotlights for this
application. Your goal as a Python developer should be to release error-free applications at all times.
course on their CHOICE
D
Course screen after However, often with short development cycles and multi-member programming teams, trying to
class for supplemental coordinate perfect code can be impossible. One small change made to a minor function can have
information and hidden side-effects in other places in the application, often written by a different team of
additional resources.
TDD
programmers.
or
Test-driven development (TDD) is a programming paradigm that attempts to minimize errors and bugs
in applications. TDD provides a framework that all developers can use to write better, more precise
code in their applications.
e
With TDD, before you write any code, you write a series of specifications (or rules) for each
at
function used in the application. The specifications define how each function works, what data it
requires, how it handles the data, and what data it produces. Consider all aspects of quality as you
write your unit tests. For example, you might include security tests to test for potential
lic
vulnerabilities you have identified. After you write the specifications, identify a series of tests that
can verify whether the code matches each specification.
Once you have designed the tests, write each function to pass the tests. A function isn't released
up
until it can pass all of the tests, ensuring that it meets all of the design specifications. By placing the
code testing at the beginning of the development cycle instead of the end, you ensure all code
matches the design specifications.
D
TDD Benefits
ot
TDD Benefits Creating a series of tests for each function within an application up-front may seem somewhat
unorthodox, but there are benefits to that process. First, by forcing developers to decide on the
specification rules first, you're forcing them to think outside of the box. Trying to determine just
N
how a function could break goes a long way in identifying problems before customers do. This
ensures that each function in an application works as expected, no matter what strange thing an
unwitting customer may throw at it.
o
Also, by writing the specification rules up-front, you ensure that all code changes made during the
D
development cycle don't break the function, or any other functions that rely on the function being
changed.
A side benefit to TDD is that it forces developers to take a modular approach to writing
applications. Instead of cramming all of the features of an application into one monolithic block of
code, TDD forces developers to split functions into separate modules. Each module provides a
separate function of the application and is defined by a separate set of specification rules. Modular
code helps the development process by not only making the application easier to manage, but also
can aid in code sharing between applications. Modules that are common between applications can
be shared.
Finally, in large programming shops, TDD helps ensure all of the developers are working off of the
same design goals. Specification rules are written to ensure proper interoperability between
functions in the application. As long as developers write to satisfy the specification rules, the
chances that changes to one function have a negative impact on another function are minimized.
Separate development teams can work on their set of functions knowing just what to expect from
other functions contained in the application.
e
Unit Testing Framework
ut
Tests are divided into three different groups: Unit Testing Framework
(2 Slides)
ib
• Unit tests—test individual functions in an application.
• Integration tests—test how separate functions interact with one another.
• Functionality tests—test how the entire application works as a whole.
tr
The simplest building block for TDD is the unit test. A unit test defines the rules required to test a
is
single unit in the application, usually a function. Each function in an application has its own unit test
rules. They define how the function should operate independent of the rest of the application.
Python has a few different libraries that provide unit test features. Currently, the most popular one
D
is the PyUnit package. The PyUnit package contains classes and methods for performing a series of
unit tests on just about any type of function. It is installed as part of the standard Python library as
the unittest library.
• Test fixtures—include code to prepare the test environment for the test, such as setting up data
e
and releasing connections.
at
• Test cases—the code used to test the specification rules against the function.
• Test suite—a collection of multiple test cases that are run together.
• Test runner—the code used to run the unit tests against the function.
lic
The TestCase class defines separate methods for each unit test. Each method name must begin
with the name test. The method contains code that defines the parameters of the test rules.
up
Assertions
The TestCase class checks rules by using assertions. An assertion is a check to determine if a rule Assertions
D
passes or fails. This is often done by testing data values, or whether or not a function exits properly
without any errors. There are several different types of assertions that the TestCase class supports.
ot
Assertion Description
Assertion Description
assertNotIn(x, y) Checks that x is not in y.
assertIsInstance(x, y) Checks if x is an instance of y.
assertNotIsInstance(x,y) Checks that x is not an instance of y.
e
def test_foo(self):
ut
self.assertEqual(foo(10), 100)
This example tests that the output from the foo() function, if sent the value of 10, is 100. If the
returned value is not 100, the assertEqual fails, and the myTest test fails.
ib
Guidelines for TDD
tr
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
is
CHOICE Course screen.
D
Test Your Code
• Direct each testing unit toward testing one small piece of functionality to prove that it works
correctly.
e
• Design each testing unit so it can run alone, as well as within the test suite, in any sequence. This
at
may mean initializing each test with a fresh dataset and performing cleanup afterwards. (You can
write setUp() and tearDown() methods to accomplish this.)
• Strive to write tests that run quickly, so they won't slow down development.
lic
• Run individual testing units frequently as you develop, and run the full suite before and after a
programming session.
up
Develop Each
Application Function Develop Each Application Function
To develop each application function:
D
• Develop the function code and run the unit test against it.
• Rewrite any function code that fails a unit test.
N
o
D
ACTIVITY 6-1
Planning for TDD
Scenario
e
You have been tasked to write a function that calculates factorials for a larger application. Your
ut
function must follow the standard math rules for factorials. It will receive a single parameter for the
input number, and should return a single number as the factorial if it succeeds, or return a False
value if it fails.
ib
Activity: Planning for
TDD
1. In a sentence or two, define what a factorial is.
tr
A: The mathematical definition for the factorial of a positive integer value is the multiplication of all the
previous integer values up to that value. Thus, the factorial of 5 is 1 * 2 * 3 * 4 * 5 = 120.
is
2. What results should be produced for special numbers and extremes. For example, what is the factorial
D
of 0? What is the factorial of a negative number?
A: The mathematical definition of the factorial of 0 is 1. There is no mathematical definition for the
factorial of a negative number. Our function will return a failure condition if the calling program
supplies a negative value.
or
3. What test cases might you use to test for various normal numbers and special numbers?
A: You might test that various positive numbers return the correct factorial value—perhaps a small,
e
medium, and large value. For example, if our test submits the value of 5 (a small number), the
factorial() function must return a value of 120. It should also ensure that submitting a value of
at
0 returns a value of 1. It should also ensure that submitting a negative value returns a False
value. While not a requirement, the factorial() function must also be able to detect if a non-
numeric value is submitted. If it detects a non-numeric value, it should also return a False value.
lic
TOPIC B
Write and Run a Unit Test Case
Once you have determined the rules required for your tests, you're ready to start coding the
TestCase.
e
Unit Test Case
ut
Unit Test Case The TestCase class for the factorial() function will consist of separate assertion tests for each
rule that must be matched. The first method must define a test to check for a valid factorial value:
ib
def test_factorial_valid(self):
self.assertEqual(factorial(5), 120)
tr
The second test method in the TestCase must test that the factorial() function returns a value
of 1 for the factorial of 0:
is
def test_factorial_zero(self):
self.assertEqual(factorial(0), 1)
D
The third method tests that the factorial() function returns a False value if you try to find the
factorial of a negative number:
def test_factorial_negative(self):
self.assertFalse(factorial(-1))
or
Finally, the fourth method tests that the factorial() function returns a False value if you submit
a text value as the parameter:
e
def test_factorial_text(self):
at
self.assertFalse(factorial("text"))
With these four tests, you're ready to code the TestCase for the factorial() function.
lic
Guidelines for Writing a Here are some guidelines to follow when designing tests for a unit test:
Unit Test • Determine the rules that define the function that's being tested.
• Create a TestCase class that contains the separate tests.
D
ACTIVITY 6-2
Writing a Unit Test
Data Files
e
All project files in Desktop\AdvPython\Implementing Unit Testing\Factorials
ut
Activity: Writing a Unit
Scenario Test
You will build the test case file to test a factorial() function. The PyCharm editor can
ib
automatically generate a unittest stub for you to build on. You'll create the factorial() function
first, then use PyCharm to start the unittest file for you. You will write methods to test for each
tr
of the cases you planned.
is
1. Launch PyCharm and open the Factorials project.
a) From the desktop, double-click the JetBrains PyCharm Community Edition 3.4 shortcut and select
D
Open Directory.
b) Navigate to the Desktop\AdvPython\Implementing Unit Testing directory, select the Factorials
project, and select OK.
3. Define the factorial() function and the code to calculate the factorial of a number.
a) Define the factorial() function.
If you would prefer that
up
Snippets.txt.
ot
N
o
a) In the def line, right-click the factorial keyword and select Go To→Test.
e
ut
ib
tr
is
D
or
You are prompted to choose the test for factorial. No tests exist yet, but you are provided with an
e
option to create one.
at
lic
The Create test dialog box is shown. Default names for the test file and test class are provided.
c) In the Create test dialog box, select the check box to generate the test_factorial test method, and
select the OK button to generate the test file.
e
ut
ib
A new test_factorial.py script is created.
tr
5. In the test_factorial.py script, add methods required to test the factorial() function.
is
a) Import the factorial() function from the factorials library file.
D
or
e
at
SNIPPET 2, provided in
Snippets.txt.
D
ot
N
o
D
ACTIVITY 6-3
Running a Unit Test
e
You have opened the Factorials project in PyCharm, and have added test cases in
ut
test_factorial.py.
Activity: Running a Unit
Test Scenario
ib
Now that you have the test code prepared, you can run the tests and observe the results. If any test
fails, you will have to modify the factorial() function code.
tr
is
1. Perform the unit tests in the test_factorial.py file.
a) Run Unitests in test_factorial.py.
D
or
e
at
lic
The unittest feature in PyCharm runs the unit tests in a special output window in the console
area.
up
b) In the left pane, examine the status of each of the unit tests you defined.
The unit tests show that one test failed . The test_factorial_text test determined if the
factorial() function rejected text as the input. The current factorial() function failed that
D
test.
2. Modify the factorial() function to add a check for text input values.
ot
e
ut
ib
tr
is
The new if statement checks whether the number variable contains a number using the
isinstance() method and the Number attribute of the numbers class. This additional check
D
requires the numbers library.
c) Add the import statement to import the numbers library.
or
e
at
lic
up
TOPIC C
Create a Test Suite
While unit tests are useful, usually, an application contains more than just one function. Fortunately,
Python also supports test suites, which enable you to perform multiple unit tests in a single test
environment.
e
ut
Unit Test Suite
Unit Test Suite Single unit tests are great for testing individual functions, but the typical Python application consists
ib
of several functions. It can be somewhat tedious creating separate unit tests for all of the functions
contained in the application. The unittest library also provides a test suite feature that allows you
tr
to group multiple unit tests into a single test group. That allows you to run the test group as a single
test and view the results.
is
The PyCharm editor provides an easy way to create test suites from classes instead of individual
functions. Just right-click on the class name in the class definition and generate the test. The
PyCharm wizard automatically detects the methods defined in the class, and offers you the option to
D
generate tests for each method.
Develop your testing code as you develop the application functionality that it will test:
• Group all of the methods into a single class object.
lic
• Select the methods that you need to test from the class methods.
• Customize the test methods to meet the rules defined for your requirements.
Testing Best Practices
D
• Direct each testing unit toward testing one piece of functionality to prove it works correctly.
• Design each testing unit so it can run alone, as well as within the test suite, in any sequence. This
may mean initializing each test with a fresh dataset, and performing cleanup afterwards. (You can
N
the bug. Tests accumulated over time will help you and other developers identify potential
problem areas, and will help to ensure that past problems don't reappear.
D
• Give your testing functions long, descriptive names. These are displayed when a test fails, so
descriptive names will be more useful. They will not be called explicitly, so you don't have to be
concerned about them cluttering your code.
• Run individual testing units frequently as you develop corresponding units of functionality.
• Run the full suite before and after each programming session.
• Run the full suite before pushing code to a shared repository.
ACTIVITY 6-4
Creating a Test Suite for Python Pizza
Calculator
e
Data Files
ut
All project files in Desktop\AdvPython\Implementing Unit Testing\PizzaCalculator
ib
PyCharm is running, and the Welcome screen is showing.
tr
Activity: Creating a Test
Scenario Suite for Python Pizza
Calculator
is
You want to test a new script you've created in the Python Pizza Calculator project. The
getPPCData.py file contains two methods that retrieve the toppings and prices inside the main
program. You will create a test suite to check these methods.
D
1. Open the PizzaCalculator project.
a) In PyCharm, select Open Directory.
or
b) Navigate to the Desktop\AdvPython\Implementing Unit Testing directory, select the PizzaCalculator
project, and select OK.
e
c) On the left side of the PyCharm window, in the Project window, verify that PizzaCalculator is listed.
at
e
ut
ib
tr
is
D
or
e
at
lic
The get_toppings() and get_prices() methods read data from the local database file and
up
3. Use PyCharm to generate the test suite for both of the methods contained in the GetPPCData class.
D
ot
N
o
D
e
ut
ib
tr
is
b) In the Choose test for GetPPCData dialog box, press Enter to display the Create test dialog box.
D
c) In the Create test dialog box, select the check boxes to generate the test_get_toppings and
test_get_prices methods, and select OK.
or
e
at
lic
up
D
4. Modify the default test suite to add tests for the get_toppings() and get_prices() methods.
N
o
D
e
ut
ib
b) On line 9, revise the self.fail() statement for the test_get_toppings() test as shown.
tr
is
D
This checks if the length of the toppings list returned matches the number of toppings you have in
the toppings table.
or
c) On line 12, revise the self.fail() statement for the test_get_prices() test as shown.
e
at
lic
up
D
ot
N
o
D
ACTIVITY 6-5
Running a Test Suite
e
You have created the test suite for the PizzaCalculator project, which is open in PyCharm.
ut
Activity: Running a Test
Scenario Suite
You will run the test suite you built for the GetPPCData class methods to determine if the code you
ib
created passes the tests.
tr
1. Run the test_getPPCData.py test suite file.
is
a) Run ppc-server.py.
When the server runs, it displays the "Listening for a client" message in the console.
D
b) Run Unittests in test_getPPCData.py.
c) Observe the unit test output in the console window. Both tests should have completed successfully. Toggle using soft wraps
in the current editor;
Summary
In this lesson, you used Python's unit testing capabilities to test your Python applications.
Encourage students to
use the social Will you use unit testing in your own applications?
networking tools A: Some developers view the writing of test functions as additional, unnecessary programming overhead.
provided on the CHOICE Many developers, however, find that unit testing helps them produce robust code. Many believe that
Course screen to follow
e
the process of designing test cases and writing modular code (driven by unit testing) enforces a
up with their peers after
discipline that leads to better applications. With experience, many developers find they can write code
ut
the course is completed
more quickly when they are using unit testing because of the problems they avoid.
for further discussion
and resources to support How will your own development projects benefit from automated unit testing?
ib
continued learning.
A: Answers will vary. TDD enables you to make significant changes to code and relatively quickly
determine if those changes have inadvertently affected the functionality of the program. They can
tr
help you and other team members avoid producing inadvertent side effects or bugs, especially in
large, complex projects, or projects in which multiple developers are working.
is
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
peers, and the larger CHOICE online community about the topics covered in this course or
D
other topics you are interested in. From the Course screen you can also access available
resources for a more continuous learning experience.
or
e
at
lic
up
D
ot
N
o
D
e
ut
Lesson Time: 2 hours, 10 minutes
ib
tr
is
Lesson Objectives
D
In this lesson, you will:
Lesson Introduction
lic
Once you've created an application, you may want to think about sharing it with the world.
The default Python® installation includes utilities to help you bundle all of the files required
for your application into one place for easy distribution.
up
D
ot
N
o
D
144 | Python® Programming: Advanced
TOPIC A
Create a Package Structure
Python packages rely on a standard structure so installation programs can easily install them in any
Python installation environment.
e
You may want show the
Spotlight presentations Note: To learn more, view the Spotlight presentations from the Spotlight tile on the CHOICE
ut
from the CHOICE course screen.
Course screen or have
students navigate out to
ib
the Course screen and Package Name
watch them as a
supplement to your Now that you have a completed Python application, you may want to think about distributing it to
tr
instruction. If not, please others. Even if you don't want to share your Python application with others, you may still need to
remind students to visit install your application on multiple computers. Either way, you'll want to bundle all of the files in
the Spotlights for this
is
your application into a Python package.
course on their CHOICE
Course screen after A Python package is a standard way of bundling all of the program, data, and test files required for
D
class for supplemental an application into a single manageable folder. That folder can then be bundled for distribution
information and using any type of distribution means, such as zip files, Linux® package management tools, or the
additional resources. Windows® installer tool.
Package Name
or
Before you start packaging your Python application, though, you'll need to spend a few minutes
thinking about your package name. Because Python packages can be installed anywhere, you should
try to make your Python package name unique. You can't install two packages with the same name
in your Python environment.
e
at
PyPI
You'll also need to consider how you will distribute your packages to other users, as this will
lic
PyPI
determine what kind of package you need to create. A common means of distribution is the Python
Package Index (PyPI)) website at http://pypi.org, which is a central clearinghouse for shared Python
applications and code. When you distribute a package through PyPI, other users can download and
up
the Project Interpreter dialog box), a searchable list of available packages is shown. You simply
select a package and select the Install Package button to download and add the package to your
Python installation. Other Python programming tools and operating systems provide other
ot
e
ut
ib
tr
is
D
Figure 7-1: Selecting a package to download from PyPI.
or
Note: Even if you don't plan on distributing your application world-wide, it's always a good idea
to check out the package names in PyPI so that your package won't conflict with any other
e
popular Python package that may be installed on your system.
at
Pip Install
lic
You can download and install packages directly within PyCharm by using the Project Interpreter. Pip Install
But there may be times when you prefer to use the command line. To install packages, you can use
the pip install command.
up
You can use pip install to install packages from PyPI or another repository, as well as from
packages in a local package archive (a TAR or ZIP file) that you have already downloaded and have
in a local file.
D
Note: When you work with Python from the command line, to ensure that Python commands
such as pip install are found, make sure that you have included the important directories
within your PATH environment variable, such as C:\Python34, C:\Python34\DLLs, C:
ot
You may want to distribute your packages through means other than PyPI. You can set up your Alternate Ways to
own repository as an alternative to PyPI, or you can deliver files in a format that is ready to install Distribute Packages
D
directly. The Python distutil utility provides for packaging and installing applications using
several different formats. You can choose to distribute your application as source code for everyone
to see, or you can choose to distribute your application as compiled Python code to hide your code.
You can also choose to distribute your application using a Windows installer format, a Linux
package management format, or even a simple TAR or ZIP file. PyCharm's Tools→Run setup.py
Task menu provides a way to run one of these packaging options without having to enter
command-line commands directly.
Minimal Structure
Minimal Structure When you are preparing to create a Python distribution package, you must follow a strict structure
format. The package itself is nothing more than a package folder that contains your application files.
The folder will contain your Python code files, any data files required for your application, as well as
any unit test files that you may have built.
The key to the package folder is the __init__.py file. Its presence in a folder indicates that the folder
is a Python library and contains code files that Python should scan when searching for library
modules. The __init__.py file itself doesn't need to contain any data; it just needs to exist.
e
The main configuration file for a Python package is the setup.py file. It tells the Python installation
ut
program important information about the package. This is where you configure your application
package name, any version number information, who wrote the application, how to contact the
author, and what files need to be installed along with the program files.
ib
Dependencies
tr
Dependencies Just about every Python application requires some external libraries and/or data files to operate. For
is
example, the Python Pizza Calculator server application requires the sqlite3, socket, json,
threading, and tkinter libraries to run. These particular libraries are included in the standard
Python distribution, but you need to let the Python installer know if the package includes other
D
libraries required for your application to run properly.
You also need to let the Python installer know about any data files that the application requires. The
or
Python Pizza Calculator uses the pizza.db database file to store the toppings and price
information. Since that file is not a Python program file, it needs to be treated differently in the
package.
e
Guidelines for Packaging a Python Project
at
Note: All Guidelines for this lesson are available as checklists from the Checklist tile on the
lic
package.
• If appropriate, include documentation for your users, such as README files, requirements, and
so forth.
ot
• If possible, test the package by installing it on various computers that represent the types of
systems your end users will have and using test utilities to test the packaging.
N
• Make sure the current directory contains the archive file for the package you want to install.
• Type pip install followed by a space and the name of the package you want to install—for
example pip install pyinstaller-3.2.zip.
• Press Enter.
e
• Select Install Package.
ut
Access the Checklist tile on your CHOICE Course screen for reference information and
ib
job aids on How to Create and Install Packages.
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
ACTIVITY 7-1
Creating a Package Structure
Data Files
e
All project files in Desktop\AdvPython\Packaging an Application for Distribution\PizzaServer.
ut
Activity: Creating a
Package Structure Scenario
You are ready to package the Python Pizza Calculator server so it can be installed on other
ib
computers. Before you can begin, you'll need to use PyCharm to create the basic structure for your
application.
tr
is
1. Launch PyCharm and open the Python Pizza Calculator server project.
a) Launch JetBrains PyCharm Community Edition 3.4.
b) Select Open Directory and navigate to Desktop\AdvPython\Packaging an Application for
D
Distribution.
c) Select PizzaServer and select OK.
or
2. Create a Python package folder in the project.
a) In the left window, right-click on the PizzaServer project name.
b) From the menu, select New→Python Package.
e
c) In the Enter new package name text box, type pizzaserver and select OK.
The new pizzaserver package folder is created in the project folder. It contains an empty initialization
at
file, __init.py__.
d) Observe the package folder.
lic
e
ut
ib
d) Select OK.
tr
The files are now indented beneath the pizzaserver package folder, so they will all be included in the
package.
is
4. Create a setup.py file for your project.
D
a) In the left window, select the PizzaServer project.
Note: Be careful to select the PizzaServer project folder, not the pizzaserver
package folder.
b) From the PyCharm menu bar, select Tools→Create setup.py.
c) Fill in the New Setup Script form with the package information.
or
e
at
lic
up
D
ot
N
o
D
e
a) Open setup.py for editing.
ut
b) Examine setup.py.
ib
tr
is
D
or
The setup is initialized using the values you provided. If you needed to add package dependencies,
e
you could modify the packages value to include more package names after 'pizzaserver'.
at
lic
up
D
ot
N
o
D
TOPIC B
Generate the Package Distribution Files
Once you've completed configuring the setup.py file, you're ready to bundle your application for
distribution. There are several different ways you can bundle your package.
e
Packaging Options
ut
When you create a package using either the Run setup.py Task menu from PyCharm or Packaging Options
setuptools from the command line, you'll need to specify the type of packaging operation you
ib
want to perform. Typical options include the following.
tr
Item Description
is
bdist_dumb Create a "dumb" built distribution.
Create an executable installer for Microsoft® Windows®.
D
bdist_msi
bdist_rpm Create an RPM distribution.
bdist_wininst
build
build_py
Build everything needed to install. or
Create an executable installer for Microsoft Windows.
When you using PyCharm's Run setup.py Task menu to generate a package, you are prompted to
o
select an option. Each option may include its own assortment of settings, which are presented in
PyCharm through a dialog box.
D
Access the Checklist tile on your CHOICE Course screen for reference information and
job aids on How to Generate Package Distribution Files.
ACTIVITY 7-2
Packaging the Python Pizza Application
Scenario
e
You have prepared the Python Pizza Calculator server application for the packaging process. All
ut
that is left now is to generate and release the distribution files.
Activity: Packaging the
Python Pizza Application
ib
1. Run the packaging task.
a) In the PyCharm window, select the PizzaServer project.
tr
b) Select Tools→Run setup.py Task.
c) Scroll to view the various types of packages you can build.
is
D
or
e
at
lic
up
d) Type sdist to select the sdist distribution method, and press Enter.
D
e) If the only option shown in the Run Setup Task sdist dialog box is Command Line, then select
Expand Options.
ot
N
o
D
e
ut
ib
tr
is
D
or
e
at
window.
The folder contains a ZIP file that in turn contains the application package.
D
e
ut
ib
3. Examine the ZIP file.
a) In the File Explorer window, double-click PizzaClient-1.0.zip to open it as a compressed folder.
The ZIP file contains one folder, PizzaServer-1.0.
tr
b) Open PizzaServer-1.0.
The package includes a setup.py script, PKG-INFO file, and pizzaserver folder.
is
c) Open pizzaserver.
The folder includes all of the Python files you included in the package folder, but not the pizza.db
D
database file.
d) Close the File Explorer window.
d) Select OK.
The distribution is created, replacing the old ZIP file with a new one.
D
The folder includes all of the Python files you included in the package folder, as well as the pizza.db
database file.
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
TOPIC C
Generate a Windows Executable
You've created an application that you want to distribute to users who do not have Python installed
on their computer. Fortunately, you can provide the application along with its own instance of
Python, essentially delivering a complete Windows executable version of the application.
e
ut
PyInstaller
PyInstaller PyInstaller is a Python package that bundles a Python application and all of its dependencies
ib
(including Python itself) into a complete deliverable. A user can run the packaged application
without having to install a separate Python interpreter and related support modules. PyInstaller
tr
works with Python applications created in Python 2.7 and Python 3.3 and later. It supports both
windowed (for example, those that use wxPython) and console apps.
is
PyInstaller works with Windows, Mac OS X®, and Linux. But it does not generate packages across
platforms. For example, to create a Windows executable package, you must run PyInstaller on a
Windows computer. PyInstaller is available through PyPI, and other sources such as GitHub® and
D
the PyInstaller website (www.pyinstaller.org).
or
Access the Checklist tile on your CHOICE Course screen for reference information and
job aids on How to Generate a Windows Executable.
e
at
lic
up
D
ot
N
o
D
ACTIVITY 7-3
Generating a Windows Executable
Data Files
e
Desktop\AdvPython\Packaging an Application for Distribution\Install\PyInstaller-3.2.zip
ut
All project files in Desktop\AdvPython\Packaging an Application for Distribution\PizzaClient
Generating a Windows
Scenario Executable
ib
Computers that will run the Python Pizza Calculator client will not necessarily already have
Python installed, so you will generate a version of the application that will include its own Python
tr
runtime environment.
is
1. Locate a local copy of the PyInstaller package.
D
a) In File Explorer, open the AdvPython folder.
b) Open the Packaging an Application for Distribution folder.
c) Open the Install folder.
or
e
at
lic
This folder contains the PyInstaller package in the PyInstaller-3.2.zip file. You will use Pip to install
up
the package.
a) In the File Explorer window, click a blank area to make sure no file is selected.
b) In the File Explorer window, press and hold Shift and then right-click a blank area. Select Open
command window here.
ot
3. Launch PyCharm and open the Python Pizza Calculator client project.
a) Launch JetBrains PyCharm Community Edition 3.4.
D
c) PyInstaller runs in the project directory and creates a build and dist folder.
e
d) In the Project window, right-click ppc-threaded-server.py, and select Run 'ppc-threaded-server'.
ut
ib
tr
is
D
e) Minimize the PyCharm window.
or
e
The server will continue running with the window minimized.
at
\PizzaClient.
The build and dist folders created by PyInstaller are visible here.
up
D
ot
N
o
D
e
ut
ib
tr
is
D
This directory contains the files you would distribute to users. These include the ppc-client.exe
executable file, along with runtime files needed to provide the Python environment.
c) Open ppc-client.exe.
or
A console window runs, from which the Python Pizza Calculator is launched. The console output
from your application would appear in the console window, although PyInstaller includes an option to
create an executable that does not display the console window.
e
d) Select Large, Pepperoni, and Calculate Price and verify the application returns a Total of 14.49.
e) Close the Python Pizza Calculator window to exit the application.
at
window here.
You can run PyInstaller directly from a command console (outside of PyCharm).
d) Type pyinstaller ppc-client.py -w and press Enter.
D
You are prompted to replace the previous build that you created.
e) Type y and press Enter.
ot
b) Open ppc-client.exe.
The Python Pizza Calculator is launched without a console window.
o
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
Summary
In this lesson, you created a package structure for a Python application project, and you generated
distribution files.
Encourage students to
Will you distribute your Python applications to other users? use the social
A: Answers may vary. Some Python programmers only develop applications for their own use, so networking tools
e
distribution may not be a matter of concern for them. However, if you intend to distribute your provided on the CHOICE
applications to other users, you should spend some time getting familiar with the packaging options Course screen to follow
ut
up with their peers after
provided for Python.
the course is completed
What sorts of distribution options will you use to distribute your packages? for further discussion
ib
and resources to support
A: Answers will vary, depending on your users, the computer operating systems they use, and whether continued learning.
they already have Python installed.
tr
Note: Check your CHOICE Course screen for opportunities to interact with your classmates,
peers, and the larger CHOICE online community about the topics covered in this course or
is
other topics you are interested in. From the Course screen you can also access available
resources for a more continuous learning experience.
D
or
e
at
lic
up
D
ot
N
o
D
Course Follow-Up
Congratulations! You have completed the Python® Programming: Advanced course. You have
successfully created, tested, packaged, and delivered Python applications that include graphical user
interfaces, networking, database, and threading features.
What's Next?
Programming Google App Engine™ Applications in Python® will show you how to use your Python skills
e
to develop web applications that take advantage of Google cloud services. In this course, you will
learn how to create web applications powered by Google's App Engine, a cloud computing
ut
platform. You'll learn how to program these apps in Python and supplement them with languages
like HTML and CSS.
ib
You are encouraged to explore Python further by actively participating in any of the social media
forums set up by your instructor or training administrator through the Social Media tile on the
CHOICE Course screen. You may also wish to explore the official Python documentation website
tr
at https://docs.python.org/3/ for more information about the language.
is
D
or
e
at
lic
up
D
ot
N
o
D
Course Follow up
D
o
N
ot
D
up
lic
at
e
or
D
is
tr
ib
ut
e
Solutions
e
ut
ib
ACTIVITY 2-1: Designing a GUI
tr
is
2. How many windows will the application use?
A: While applications may have multiple windows, this application is simple enough that it can
be implemented in one window.
D
3. What type of widget(s) might you provide to enable the user to select a pizza size?
or
A: Since only one size should be selected from the three options, a group of radio buttons is
probably the most appropriate choice for this. Another option would be a list box configured to
allow only one item to be selected.
4. What type of widget(s) might you provide to enable the user to select toppings?
e
A: Since no selection, one selection, or multiple selections should be allowed, a group of check
at
boxes would be an appropriate choice for this. Another option would be a list box configured to
allow multiple items to be selected.
lic
5. What type of widget(s) might you provide to enable the user to clear (reset) the selections?
A: A button would be appropriate for this. When selected, a Reset button could trigger an
action that resets the application widgets back to their original selection states.
up
6. What type of widget(s) might you provide to enable the user to calculate the total?
A: A label or text box could be used to display the resulting price. There are different ways to
trigger the calculation. For example, you might calculate a new result automatically each time
D
the user changes the size or toppings. Or you might provide a separate Calculate price button
that displays the updated total when the user selects the button.
ot
A: For the Python Pizza Calculator, three data elements will be needed: the list of toppings, the
pizza price for each size, and the price for toppings for each pizza size.
D
2. What groups of common data will be needed to contain the data elements?
A: The data normalization process can be somewhat subjective and tricky. First, determine the
common groups for the data. While there may be various ways of doing this, for the Python
Pizza Calculator, you'll provide two general categories of data elements: toppings and prices.
166 | Python® Programming: Advanced
e
pizza size and topping size as a text value, again using the varchar data type. You'll
also use the 15-character data constraint for this data field. For the price data field, you'll
ut
need to store the product price as a dollar amount, including two decimal places for the
cents. You'll use the decimal data type to do that.
ib
ACTIVITY 4-1: Defining an Application Protocol for
tr
the Python Pizza Calculator
is
1. What connection protocol and port will you use for the application?
D
A: Since the Python Pizza Calculator needs to accurately send topping and price data
across the network, TCP is an appropriate choice. Regarding the port, many numbers are
available and appropriate. (In the activity, you'll use port 8000.)
A: Since customers will run the Python Pizza Calculator window, you'll use that as the
e
client device. You'll create a separate server program to serve the toppings list and prices
dictionary values. The server will listen on TCP port 8000 and the client (the Python Pizza
at
toppings, prices, or terminate the connection (exit). The client will send these as text
commands to the server. The server will return data in response to received client
commands. If the server receives a topping command, it will send the toppings list. If
the server receives a prices command, it will send the prices dictionary object. Finally, if
ot
the server receives an exit command, it will terminate the connection with the client.
N
Solutions
Python® Programming: Advanced | 167
2. What results should be produced for special numbers and extremes. For example, what is the factorial
of 0? What is the factorial of a negative number?
A: The mathematical definition of the factorial of 0 is 1. There is no mathematical definition for the
factorial of a negative number. Our function will return a failure condition if the calling program supplies
a negative value.
3. What test cases might you use to test for various normal numbers and special numbers?
A: You might test that various positive numbers return the correct factorial value—perhaps a small,
medium, and large value. For example, if our test submits the value of 5 (a small number), the
e
factorial() function must return a value of 120. It should also ensure that submitting a value of 0
returns a value of 1. It should also ensure that submitting a negative value returns a False value. While
ut
not a requirement, the factorial() function must also be able to detect if a non-numeric value is
submitted. If it detects a non-numeric value, it should also return a False value. These can serve as
the basis for your tests.
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D
Solutions
D
o
N
ot
D
up
lic
at
e
or
D
is
tr
ib
ut
e
Glossary
e
ut
ib
assertion constructor
A statement in a unit test function that A special method, defined within a class
tr
determines if a particular rule passes or using the __init__ keyword, that runs
fails. when an object of that class is instantiated.
is
attribute cursor
D
Features of an object (such as the weight, A pointer to a particular storage location
engine, and number of doors of a car). A within a database, which you can use to
class can contain many attributes, each navigate through a database and
class
or
describing a different feature of the object. manipulate individual objects in the
database.
daemon
e
Data and functions, grouped together into
a single entity, that can be instantiated to Processes that run in the background and
at
less than, etc.). Python provides a variety being accessed within a file.
of standard comparison methods that you
can customize in your own classes to frame
enable objects of that class to be easily An object that serves as the main content
compared. area for a window, which contains other
170 | Python® Programming: Advanced
e
components within a window, which
A scheme for laying out user interface requires you to provide a specific X,Y
ut
components within a window, which uses location for each widget.
a system of columns and rows to position
components. property
ib
A protected attribute of a class that can be
inheritance set only by using special instance methods
tr
An aspect of object-oriented programming called setters, and whose values can be
that enables developers to define a subclass read only by using special class methods
is
that inherits attributes and methods of a called getters.
superclass.
D
PyInstaller
locking A Python package that bundles a Python
A Python feature that enables one thread application and all of its dependencies,
of execution to place a hold on processing
while it performs a crucial code segment.
While the lock is in place, the operating
system blocks any other threads from
or including Python, into a complete
deliverable.
PyPI
e
running. (Python Package Index) A central
at
method setter
D
Glossary
Python® Programming: Advanced | 171
TDD
(test-driven development) A software
development methodology that involves
e
designing and implementing tests before
writing the code that will be tested. Because
ut
tests are created first, they can be used to drive
development. Once a unit of code is thought
ib
to be complete, it can be tested and modified
repeatedly until it passes testing. Once a unit
has passed, its unit tests can remain in place to
tr
ensure that if changes are made to code later
on, they do not cause the code fail.
is
threading
D
A means of coordinating the execution of
multiple blocks of code that can share the
same data.
transaction
A means of grouping a series of database
or
e
manipulation tasks such that all of the tasks
must complete successfully. If any task is
at
completed.
widget
A user interface component.
up
wireframe
A type of drawing or diagram that illustrates
D
Glossary
D
o
N
ot
D
up
lic
at
e
or
D
is
tr
ib
ut
e
Index
e
ut
ib
tr
A E
is
assertions 127 event handlers 47
attributes events 47
defined 2
D
F
C factory method 25
classes
defined 2
class factories
or
G
e
abstract 26 getters 5
polymorphic 25 graphical user interface, See GUI
at
D
I
daemons 104
D
data types 61
supported by Python 61 J
data corruption json library 91
N
files 60 libraries
D
M setters 5
socket library
magic methods 15
client 90
menu bars 49
common methods 89
methods
server 89
class 3
SQLite3
comparison 16
database construction 65
constructor 15
database methods 64
defined 2
e
database queries 75
destructor 15
overview 64
ut
factory 25
subclass 7
instance 3
superclass 7
magic 15
ib
synchronization
numeric 18
locking feature 112
overview 3
tr
property 6
multiprocessing T
is
vs. threading 113 TCP 86
TDD
D
N benefits 126
overview 126
network programming
three groups of testing 127
client/server paradigm 86
TCP 86
UDP 86
numeric methods 18
or
test-driven development, See TDD
threading
overview 104
e
vs. multiprocessing 113
threading library 104
at
PyInstaller 156
unit testing
PyPI 144
assertions 127
packing method 40
framework 127
ot
positional method 40
TestCase class 130
properties 5
unittest library 127
property method 6
N
W
D
Q
window positioning methods 40
queue library 113
wireframe 35
S
serialization 91
Index
e
ut
ib
tr
is
D
or
e
at
lic
up
D
ot
N
o
D