Python Debugging Handbook.marking
Python Debugging Handbook.marking
Python Debugging
RL Zimmerman
3
Table of Contents
1. Introduction
1.1 Overview
1.2 What This Book is About
1.3 What’s Next?
2. Debugging Overview
2.1 Plan for Debugging
Start Small
Keep Multiple Versions of Your Code
Intended Outcome
Test Data Files
Plan for Tomorrow
2.2 Debugging Steps
Logbook
Divide and Conquer
Backup Files Before Debugging
Problem Statement
4
Doubt Everything
Look Around Your Environment
Create a List of Suspects
What Do You Think is the Cause?
Refine Your Experiment
Experiment
Success at Last
2.3 The Debugging Environment
Python
Anaconda
Spyder
Run a Script or Program
2.4 Help
2.5 What’s Next?
3. Python Basics
3.1 Statements
3.2 Python Syntax
3.3 Objects
3.4 Immutable Objects
3.5 Variables
3.6 Types of Data
5
What is the Data Type?
Converting Data Types
The ‘None’ Value
3.7 Numbers
3.8 Strings
3.9 Introduction to Data
Structures
3.10 List
Iterate Through Items in a List
3.11 Tuple
Iterate Through Items in a Tuple
3.12 Dictionary
Create a Dictionary
Assign a Dictionary Value Using the Key
Name
Add a New Key to an Existing Dictionary
Iterate Through Key-Pairs in a Dictionary
Iterate Through Keys in a Dictionary
Access the Value of a Dictionary Item
3.13 Set
3.14 Comparison Operators
3.15 Control Statements
6
3.16 Indented Code (a Suite)
3.17 Functions and Methods
Defining a Function
Parameters
Arguments
KEYWORD ARGUMENTS
POSITIONAL ARGUMENTS
OPTIONAL ARGUMENTS
AN ARBITRARY NUMBER OF ARGUMENTS
HOW TO VIEW THE FUNCTION ARGUMENT DEFINITION
Calling a Function or Method
Function Return Value
All Paths Do Not Have a Return Value
More than One Return Value
The Type of Return Value
3.18 Classes
Create a Class
The DocString
Variables - Attributes
Instance Variables and Class Variables
Create an Instance of the Class
Methods
Dotted Notation for Attributes
Calling a Method
3.19 Attributes
7
4. Debugging Tools
4.1 Debugging Overview
4.2 Add Print Statements to Your
Script
Indenting Loop Print Statements
4.3 Debug Mode
End Debug Mode
4.4 Variable Explorer
4.5 Example: My Program Loops
and Never Ends
4.6 Debug Commands
4.7 Interactive Mode
Increment Counters in the Console
Watch Out for Changing Values
iPython Session
4.8 Introspection
Variables and Objects in Memory
Using ? in the Console
dir()
help()
The Inspect Library
8
The type() Function
The id() Function
The repr() Function
The len() Function
4.9 Logging
4.10 The timeit() Function
4.11 Focused Testing
Actual Result
Incorrect Code
4.12 Create Test Data
5. Exceptions
5.1 Kinds of Errors
Syntax
Logic or Semantic
Runtime
5.2 The Stack Trace or Traceback
Don’t Be Fooled
5.3 Try and Except
5.4 Raise
5.5 Assert
5.6 Built-in Error Types
9
ArithmeticError
AssertionError
AttributeError
EOFError
FloatingPointError
ImportError
Indentation Error
IndexError
IOError
KeyError
KeyboardInterrupt
LookupError
MemoryError
ModuleNotFoundError
NameError
OSError
OverflowError
RecursionError
RuntimeError
StopIteration
SyntaxError
TabError
SystemError
SystemExit
TypeError
ValueError
ZeroDivisionError
10
6. Try This
6.1 What is the Object Value?
6.2 String and Number Variable
Values
Print the Value of a String Variable
Inspect a Number Variable in Debug Mode
Inspect a String Value with Interactive Mode
6.3 Tuple Objects and Values
Print All Tuple Item Values
Print a Tuple Item Value
Inspect All Tuple Items in Interactive Mode
Inspect A Tuple Item in Interactive Mode
6.4 List Objects and Values
Print All List Item Values
Print the Value of a List Item
Inspect a List Item in Debug Mode
Inspect All Items of a List in the Console
Inspect a List Item in the Console
6.5 Dictionary Objects and
Values
Print the Value of a Dictionary Key-Pair
Inspect All Dictionary Items in the Console
Inspect a Dictionary Item Value in the
Console
11
Inspect a Dictionary Item in Variable Explorer
6.6 Does the Object have a Value
of None or Whitespace?
Whitepsace
6.7 What is the Object Type?
6.8 What is the Length of the
Object?
6.9 What are the Function
Arguments?
The Function Call Signature
6.10 What is the Return Object of
the Function?
7. Examples
Ex 7.1 List Index Out of Range
Intended Outcome
Actual Result
Incorrect Code
Debugging Experiment
How to Resolve the Issue
Good Code
Reference
Ex 7.2 Index Error
12
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.3 Wrong Variable
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.4 Invalid Assignment
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.5 While Indentation Error
Intended Outcome
Actual Result
13
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.6 Incorrect Method
Arguments
Intended Outcome
Actual Result
Incorrect Code
Debugging Experiment
How to Resolve the Issue
Good Code
Reference
Ex 7.7 Empty Block of Code
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.8 Parentheses Not Matched
Intended Outcome
Actual Result
Incorrect Code
14
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.9 Missing Colon
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.10 Case Sensitive
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.11 Missing Keyword
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
15
Good Code
Reference
Ex 7.12 Illegal Character
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.13 Undefined Name
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.14 FileNotFound
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
16
Ex 7.15 Error Adding Numbers
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.16 Misspelled Keyword
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.17 Value is None
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.18 Method Not Found
Intended Outcome
17
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.19 Module Not Found
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.20 Key Not in Dictionary
Intended Outcome
Actual Result
Incorrect Code
Debugging Experiment
How to Resolve the Issue
Good Code
Additional Troubleshooting
Reference
Ex 7.21 Incorrect Argument Type
Intended Outcome
Actual Result
18
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.22 Name Error
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.23 Value Error
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Ex 7.24 Divide by Zero Error
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
19
How to Resolve the Issue
Good Code
Reference
Ex 7.25 Math Logic Error
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Ex 7.26 ValueError Assigning
Date
Intended Outcome
Actual Result
Incorrect Code
Debugging Steps
How to Resolve the Issue
Good Code
Reference
Appendix - URLs
Arguments
Assert
Attributes
20
Built-in Functions
Calls
Classes
Comparisons
Containers
doctest
Functions
Glossary
The if Statement
Immutable
Inspect
Interactive Mode
Iterable and Iterations
Logging
Magic Functions
Methods
Objects
Parameters
21
The pass Statement
The return Statement
State
Statements
timeit
The try Statement
Types
Values
Conclusion
22
1. Introduction
23
God, how is this done?” Instead, you’ll know exactly how it’s
done and have fun doing it!
1.1 Overview
How you may ask, are we going to build your debugging
arsenal? Let’s begin with these topics.
25
2. Debugging Overview
26
This Chapter outlines a few suggestions to approach
programming and debugging. The Examples in Chapter 7
follow a similar methodology.
Intended Outcome : What I wanted the program to do.
Actual Result : What the program did.
Incorrect Code : A look at the code before any changes.
Debugging Experiment : What I suspect is wrong with the
program, and the steps I tried to “debug” what the program
is doing.
How to Resolve the Issue : A brief description of the
change to the code to achieve my “Intended Outcome.”
Correct Code : The finished code that works as I intended.
27
data to develop your code. When you’ve tested your code
and are confident there are no bugs, use live data
connections or real data files.
5. Keep notes of where you stopped programming and the
next steps.
Start Small
Write small chunks of code. Test and validate that piece
of code, then move on. This “Correct Code ” is also a good
baseline for backups.
Intended Outcome
While I’m not suggesting you have a vision statement for
your program, it doesn’t hurt to have an “Intended
Outcome ” of what you’re trying to accomplish. This
synopsis is beneficial in several ways:
• Pair programming, or asking for another opinion.
28
• When you check-in your code to a source control
program.
• During peer review.
• In a Sprint Review, where you demonstrate your
program to others.
In case you reach out to another programmer for
assistance, share as much information as possible.
29
file, there is an error when you try to open the file. For
example, if you open an Excel file, it may prompt you to
“fix” the data on file open.
30
4. Start with a clear Problem Statement of the defect.
5. Don’t believe everything you hear. If the original defect is
the program works with Oracle data and not Cassandra
data, verify that is really the case.
6. Examine the environment.
7. Create a list of possible suspects.
8. In case you’re out of ideas and haven’t found the defect,
take a break. Work on something else, go for a walk or
come back to the problem tomorrow.
Logbook
Keep a logbook of your debugging experiments. Write
down the steps and outcome for each task. I find writing
down my issues frees my mind from worrying about the
problem, and allows me to brainstorm at my leisure.
31
code in the topic “Focused Testing.”
Problem Statement
Develop a clear problem statement with as much detail as
possible. Who can you contact for more details? When
determining how critical the issue is, consider the impact to
business and if there is a workaround.
Doubt Everything
Verify the accuracy of the original defect report by
recreating the issue yourself.
32
successfully? Can you query the Cassandra database
outside of your program? Is the web server responding to
requests? Is one of the integrated systems down?
4. Did the program encounter an Out of Memory error?
• Your app
• The last few lines of code you changed
• Python language
• OS
• Connection to a web page
• The format of a database table or web page changed
• More than one library with the same name in different
paths
• One of your script files with the same name as a library
33
want to start investigating. Make a list of your ideas or
hypothesis of what might be wrong.
Experiment
Change one thing at a time, and observe what happens.
Please, write everything down in your logbook, noting each
step and the outcome. The simple act of writing down my
experiment forces me to pause and consider what happened
and why.
• What steps did you take?
• What did you expect to happen?
• What actually happened?
Review the experiment and see if you can come up with a
theory about the cause of the defect.
34
• Is there something you should not see?
• Do you need to refine your experiment further?
• Do you have a theory about what might be causing the
defect?
• Do all your test results fit in with your theory, or is there
one result that doesn’t quite fit? Don’t ignore the evidence
that contradicts your theory. If you you aren’t sure how
that piece of code works, dig into the code because that
might be where the problem lies.
Success at Last
The last experiment you conduct that unequivocally works
is the fix. The program does what you want, and you reach
your “Intended Outcome .”
35
Python
Python is an open-source (free) programming language
for Web Development, GUI development, Scientific and
Numeric data science, Software Development, and System
Administration. The examples use the open-source Anaconda
Data Science Distribution that includes Python version 3.7.
Spyder, the Scientific Python Development Environment,
comes with Anaconda, and I run Python scripts in Spyder
primarily on a Windows machine. For variety, I’ve also
included several examples on a MAC computer.
In this Chapter, we’ll install Anaconda and set up your
environment. If you are familiar with Python and want to
jump into debugging, feel free to skip ahead to Chapter 4.
Anaconda
Download the Anaconda Distribution that includes Python
version 3.7. Other Python versions may vary slightly
compared to the examples in this manual. When prompted,
update your path settings. The install takes a while, so you
might want to grab a cup of coffee or something.
Spyder
Spyder is an Integrated Desktop Environment or IDE.
Spyder includes an Editor, Console or Spyder Shell, Variable
Explorer, Help module, and other tools. These modules are
displayed in “Panes” in Spyder.
On a Windows machine, launch Spyder from the Start
Menu, in the Anaconda folder. On a MAC computer, open the
Anaconda Navigator and launch “Spyder.”
36
The Spyder Default Layout has three panes, as shown
below. You can return to this layout at any time from the
View menu under Windows Layouts. You can close or open
other panes to suit your preferences.
37
Figure 2.2 The iPython Console
38
on the left, and the Console window is on the right. Initially,
the Console window displays the prompt In [ 1 ]: . After I
click “Run ,” the Console window changes, as shown below.
The first output line displays the name of the program file
and the working directory.
2.4 Help
In Spyder, click on the View menu and click “Panes” to
open the “Help” pane. Now, click on the Help menu and click
on “Spyder Tutorial.” The tutorial opens in the Help pane.
The topic “Recommended first steps for Python beginners” is
an excellent resource for new programmers.
Chapter 4 demonstrates Debug Mode , Interactive Mode ,
and Variable Explorer. These tools look at your code while it’s
running, in effect, “debugging.”
To open Help for an object, place the cursor on an object
name in the Editor , press Ctrl-I, or Command-I on a MAC.
Help inspects the object and gathers docstring information.
39
2.5 What’s Next?
Your Lab environment is now setup. Let’s move on to
Chapter 3 and review a few basic Python language
guidelines.
40
3. Python Basics
41
complete Python language guide; instead, think of it as an
abbreviated part of the Python language documentation. I
need this small subset of information to demonstrate how
you will refer back to the Python documentation as you
debug your program. The “Appendix - References” at the end
of this book has links to the Python documentation related to
these topics.
3.1 Statements
The actions that a program takes are called “statements.”
42
identifier names, try an underscore. Illegal spaces can
cause a syntax error.
• The PEP 8 Style Guide suggests lowercase characters for
identifier names and functions. Classes begin with an
uppercase letter. For example, variables and list names
are lowercase.
• Python is case sensitive. There is a difference between
“myString” and “mystring.” The Python Interpreter
displays a NameError when there is a misspelled
identifier.
• When defining a function or control statement, the line
should always end with a colon.
• A data structure name should be plural, and items in the
data set should be singular. For example, a List named
“vacations” with List items: vacation[0], vacation[1], etc.
• Do not use reserved keywords as identifiers. A missing
keyword causes a SyntaxError.
• Unpaired parentheses cause a SyntaxError.
• An empty Suite (indented block of code) is illegal. See
“Indented Code (Suite)” or Example 7 for more
information.
43
Example 11
Example 12
Example 16
3.3 Objects
An object is a collection of data. Everything in Python is
an object. Objects have an identity, type, and value. The
“identifier” or “identity” of the object is the name of the
object. With the library “openpyxl ,” you assign objects to
both the workbook and worksheet, and then you use those
objects with methods to read or update values (the data).
from openpyxl import load_workbook
wb2 = load_workbook (aftfile, data_only = True)
ws2 = wb2[“ ExportedData ”]
44
Immutable objects are quicker to access, and this
improves code performance. Another advantage of
immutable objects is understandability, and knowing the
object will never change.
3.5 Variables
Think of a variable as a container to store values. When a
program runs, the value inside the variable may change. A
letter or number is a value. An assignment statement
creates a variable and assigns a value, as shown below. The
left side of an assignment statement must be a variable.
mynumber = 2000000
45
Type Description Assignment Value
int integer my_var=3 3
str string of characters my_var2=‘Hi’ Hi
float floating-point number my_var3=3.85 3.85
bool boolean (true/false) my_var4=false false
46
When my_var = 3, the statement float(my_var+5) returns
8.0 .
When my_var = 3, the statement print(34//my_var)
returns 11 .
int(my_var)
str(my_var)
float(my_var)
bool(my_var)
47
Example 17. An “if statement” that tests for a value of
“None” is shown below.
if myvar is not None:
3.7 Numbers
When assigning integer values, do not use commas.
Python interprets 2,000,000 as three integers separated by
commas.
mynumber = 2000000
In the previous example, I assign 2000000 to the integer
variable “mynumber .” For readability, you can add
underscores as a separator.
mynumber = 2_000_000
3.8 Strings
A string is a sequence of characters. To assign a value to
a string variable, use single quotes, as shown below. Strings
are immutable and can not be changed. To assign a value to
a string, use the same syntax and, in effect, create a new
string variable with the same name.
mystring = ‘books’
48
• List
• Tuple
• Dictionary
• Set
3.10 List
A list is an ordered collection of values of objects. Lists
are usually of the same type, but can be a combination of
types. A List is similar to an array in other languages. List
values are mutable; the values can change. The list can grow
or shrink as needed. A unique index (a number or name)
refers to each list item. When creating Lists use square
brackets [ ] . The index is used when updating list items.
ws1 = wb1[“ ExportedData ”]
49
Description Syntax Comments
mylist = [‘a’, ‘b’,
Create a List and assign values
‘c’]
Create a List and assign number values mylist2=[1,2,3 4]
Assign a value to the first item in the
mylist2[0] = 8
List
Access the value of the List item mylist2[1] Returns the value of the first item in the List
Use negative index numbers when counting from the
Access the value of the last List item mylist2[-1]
right
Return all items in a List mylist
for j in mylist:
print(‘mylist item is:’, mylist[j])
3.11 Tuple
A tuple is similar to a list and is immutable. Immutable
objects can not be changed. Tuples use parentheses ( ) and
can have heterogeneous data, meaning Tuples can have
different data types. Items are separated by commas. Only
immutable elements are Dictionary keys, so only Tuples can
be used as Dictionary keys. Lists are mutable and can not be
used as Dictionary keys.
50
Tuple indices must be integers or slices, not a string.
51
Description Syntax Comments
Create a Tuple and assign values mytuple = (‘a’, ‘b’,
to 4 items ‘c’, ‘d’)
Create an empty Tuple mytuple = tuple()
mytuple2 = Notice the comma at the end to instruct Python this is a
Create Tuple with one item
(‘Rachel’,) Tuple and not a String.
Assign number values to several
mytuple3 = (1, 2, 3)
Tuple items
Assign a value to the first item in mytuple4[
The first item in the Tuple has an index value of 0.
mytuple4 0]=’Apple’
View the value of the 2nd Tuple In {1]: mytuple4[1]
The Python Interpreter returns the value Orange .
item Orange
mytuple4 = ( 0 , 1 , 2 )
for k in mytuple4:
print(‘my number is:’, k)
mytuple4 = ( 0 , 1 , 2 )
for k in mytuple4:
print(‘my number is:’, mytuple4[k])
52
“IndexError ,” because there are only three objects in the
Tuple with values 1, 2, 3. Python starts counting at 0. The
print statement is using “mytuple4[k] ” or mytuple[1],
mytuple[2], and mytuple[3]. When you run the program, the
Python Interpreter warns that “3 ” is not a valid index.
mytuple4 = ( 1 , 2, 3 )
for k in mytuple4:
print(‘my number is:’, mytuple4[k])
3.12 Dictionary
A Dictionary is an ordered set of key/value pairs.
Dictionaries are often depicted as two columns, with the list
of keys in the first column, and values in the second column.
Only immutable elements can be used as Dictionary keys, so
while Tuples can be used as Dictionary keys, Lists are
mutable and can not be used as Dictionary keys.
53
Key Value
Name John
Age 32
Height5.10”
Create a Dictionary
To create a Dictionary with three key pairs, use the
following syntax. For readability, the key pairs are usually
written in this format.
54
Add a New Key to an Existing
Dictionary
To add a new key, ‘Credits’ to an existing Dictionary, use
this syntax.
mydictionary[‘Credits’] = ’3’
55
The next example is the same statement with the keys()
method.
In [ 1 ] : mydictionary[‘Name’]
Zimmerman
3.13 Set
A Set is unordered objects and contains no duplicates. A
Set grows or shrinks as needed. When working with Sets,
there are functions to perform Unions, Intersections, and find
56
Differences. When creating a set, use curly braces {} and
separate items with a comma. The second row in the table
below creates a set with one item. Notice the line ends in a
comma, to indicate to Python this is a Set and not a String.
57
Description Syntax Comments
Create a Set and assign values myset = {‘a’, ‘b’, ‘c’}
Create a Set with one item myset2 = {‘John’,}
Create an empty Set myset3 = set()
Create a Set and assign values myset3 = set(‘abc’) With set() function
58
lines are all indented to the same level.
The first line of the control statement, and all the
indented lines that follow, is called a “Suite” in Python. Other
programming languages often refer to this structure as a
block of code.
A control statement moves through items in a data
structure. When this program runs, each time the program
loops through the code, the next item in the list is displayed.
fruits = [‘Apple’,‘Orange’, ‘Watermelon’]
for fruit in fruits:
print(‘my fruit is:’, fruit)
59
Let’s look at the code on lines 29, 30, 31, 32, and 48.
These lines are all indented to the same vertical level. This
code Suite, or block of code, begins on line 28. The last line
in this code Suite is line 48.
60
Indentation in Python scripts defines a “Suite” or code
block.
61
Figure 3.2 An Indented “Suite” or Block of Code
In Python, an empty Suite (indented block of code) is
illegal. For example, an “if statement” that does nothing is
illegal. Instead, use the “pass” function when your code
should take no action, as shown in Chapter 7, Example 7.
These Chapter 7 examples illustrate a few List errors:
Example 1
Example 2
62
Defining a Function
When defining a function in the Editor , the parameters
in parentheses specify what types of arguments (values) the
function can accept. In my earlier example, the parameter
“special” assigned a default boolean value of “False.” The
“special” parameter has a type of “boolean.”
def menu (meal, special=False):
1 msg = ““
2 if special is True:
3 msg = ‘The specials today are
4 Mimosas. ‘
5 if meal == ‘breakfast’:
6 msg = ‘Breakfast is eggs and
7 toast. ‘
8 else :
9 msg = ‘Sorry, we ran out of food.
‘
return msg
Parameters
In this example, there are two parameters in the function
definition, “meal” and “special.”
63
Parameter Name Default Value Required/Optional
Positional meal Required
Keyword special False Optional
Arguments
Arguments are the values you pass to a function when
calling the function. Not all functions have arguments. In this
example, the function has two arguments.
64
menu (‘breakfast’, special=True):
Parameter Argument
Order
Name Value
1 meal breakfast
2 special True
Keyword Arguments
The second parameter in my function definition includes
the keyword “special” with a default value of “False .” When
calling a function, a name precedes the keyword argument.
List keyword arguments at the end of the parenthesized list,
after positional arguments. In this example, the keyword
name is “special.”
Positional Arguments
The “meal” argument is a positional argument because it
does not have a keyword. List positional arguments before
any keyword arguments.
The example below is invalid because a positional
argument is after a keyword argument.
def menu (special=False, meal):
Optional Arguments
Because “special” has a default value, when calling the
function, “special” is an optional argument. If you don’t
provide the argument when calling the function, Python uses
the default value “False .”
65
line 1, there are two parameters enclosed in parenthesis:
66
def print_tickets(number_of_tickets, *name):
1
i=0
2
while i < number_of_tickets:
3
print(name[i])
4
i += 1
5
print_tickets(3 , ‘Carter’, ‘Rachel’,
6
‘Michael’)
number_of_tickets
*name
When I call the function on line 8, I pass it four values or
arguments. Three of the arguments are names.
print_tickets(3 , ‘Carter’, ‘Rachel’, ‘Michael’)
67
In [3]: from inspect import signature
In [4]: print(str(signature (menu)))
(meal, special=False)
In [5]:
68
container like a tuple with several items. When a function
doesn’t specify a return value, it returns the special value
“None. ” For debugging purposes, let’s look at the function
return object in terms of:
69
More than One Return Value
Occasionally, functions return more than one value. For
example, a function may return a tuple or list. In the next
example, I pass the function’s return values to mytxt .
Because the function returns two values on line 10 in a tuple,
the Console displays an error.
70
Figure 3.3 Multiple Return Values
To fix my program, I need to change line 17 to print each
element in the “mytxt ” tuple, as shown below.
print (mytxt[0 ], mytxt[1 ])
3.18 Classes
This topic provides a brief overview of classes. The
docs.ptyhon.org website has a tutorial on classes and
explains the concept of “self” in great detail.
71
• Create a Class
• The DocString
• Variables - Attributes
• Create an Instance of the Class
• Methods
• Dotted Notation for Attributes
• Calling a Method
72
class Car():
“””This class represents a car.”””
1 yr = 2020
2 def __init__(self , model, make, year):
3 “””Initialize model, make, and year
4 variables.”””
5 self .model = model
6 self .make = make
7 self .year = year
8 def drive(self ):
9 “””Move the car.”””
10 print(self .model.title() + “ is now
11 moving.”)
12def parallelpark(self):
13 “””Parallel park the car.”””
14 print(self .model.title() + “ is now
15 parking.”)
16my_car = Car(‘Subaru’, ‘Crosstrek’, 2019 )
17print(my_car.model, my_car.make,
my_car.year)
my_car.parallelpark()
Create a Class
In this class example, the first line creates a class named
“Car.” Class names begin with a capital letter, to differentiate
them from function names which should be lowercase.
The DocString
Lines 2, 5, 10, and 13 look like comments, but are
actually examples of a “DocString.” The Chapter 6 topic, “The
Function Call Signature ,” explains how to work with the
“inspect” module and view a DocString signature.
The function help() reads the docstring when gathering
information about an object.
Variables - Attributes
Beginning with the function definition on line 4, you can
73
def __init__( self , model, make, year):
self
model
make
year
When working with the “my_car” instance of the Car
class, use dotted notation to reference the variables.
my_car.model
my_car.make
my_car.year
When referring to the state of an object, you are referring
to variables or data attributes . The variables model ,
make , and year on lines 6, 7, and 8, respectively, are
accessible through instances.
self .model = model
self .make = make
self .year = year
The statement below is invalid because there is no
attribute named “color. ” When I run this program, the
Python Interpreter displays an AttributeError in the
Console .
my_car.color
In Chapter 7, Example 6 illustrates an error with an
incorrect call for a class method, which causes an
AttributeError.
74
variables and methods. For example, all instances of the Car
class share the class variable “yr ” I created on line 3.
Methods
A function that is part of a class is called a “method .”
When referring to the behavior of an object, you are
discussing the function or method. The “Car” class has two
methods, defined in lines 11 and 15. The “drive” method is
shown below.
def drive(self ):
“””Move the car.”””
print(self .model.title() + “ is now moving.”)
75
Calling a Method
To call a method in a class instance, use the syntax
shown in line 17.
my_car.parallelpark()
76
At the end of this book, the Appendix - Reference has
links for more information on Classes, Functions,
Methods, Attributes, and Instances.
3.19 Attributes
The Chapter 4 topic, “Variables and Objects in Memory ,”
discusses the current namespace and the concept of
attributes. The Python glossary entry for “attributes” is “a
value associated with an object which is referenced by name
using dotted expressions.”
In the Chapter 2 example, we looked at a line of code
with a number variable.
myint = 57
print(myint.upper)
77
method in the my_car instance of the “Car” Class.
my_car.yr
my_car.drive
78
4. Debugging Tools
79
• Using Interactive Mode in the Console .
80
variable in the current context.
Interactive Mode in the Console allows you to type
commands that display object values. In the Console type
the name, or identifier, of the object. The Python Interpreter
returns the value of the identifier. The object can be an
integer variable, a list item, tuple, or another type of object.
In the Console , you can also run individual lines of code
while developing or testing your code. Interactive Mode is a
great way to test code before adding it to your script. You
can also set a “breakpoint” to move to a particular location in
your program.
81
1 meals = [‘breakfast’ , ‘lunch’ , ‘snack’ , ‘dinner’ ]
2 fruits = [‘apple’ , ‘orange’ , ‘grape’ ]
3 i=0
4 while i < 4 :
5 j=0
6 print (“my meal is: ” , meals[i])
7 while j < 4 :
8 print(“My choice of fruit is: ” ,
9 fruits[j])
10 print (“j is: ” , j)
11 j=j+1
12 i=i+1
In [1 ]: my meal is: breakfast
my meal is: breakfast
my meal is: breakfast
my meal is: breakfast
my meal is: breakfast
my meal is: breakfast
my meal is: breakfast
82
meals = [‘breakfast’ , ‘lunch’ , ‘snack’ , ‘dinner’
1
]
2
fruits = [‘apple’ , ‘orange’ , ‘grape’ ]
3
i=0
4
level = ““
5
while i < 4 :
6
level = level + “.... ”
7
print(“my meal is: ” , fmeals[i])
8
i=i+1
83
iPython debugger is active.
84
1
mystring = “purple peanuts”
2
print (mystring)
3
In [1 ]: debugfile(‘C:/SampleScript.py’,
wdir=’C:’)
>C:\SampleScript.py(1)<module >()
---->1 mystring = “purple peanuts ”
2
3 print (mystring)
ipdb>
ipdb>
85
enter several times to quit Debug Mode, or type Esc + Enter
. You can also restart the kernel when you select “Restart
Kernel” from the Consoles menu.
ipdb>C:\SampleScript.py(1)<module >()
1 mystring = “purple peanuts ”
2
---->3 print (mystring)
ipdb>
ipdb>quit
In [2 ]:
Table 4.2 Quit Debug Mode
86
program. Next, I’ll use Debug Mode to step through the code
and identify what is happening.
87
Figure 4.3 Add a Breakpoint
4. The Console prompt changes to ipdb> to indicate the
iPython Debugger is active, and the Variable explorer
displays values for the current active variables. Right
now, the variable cnt has a value of 1 .
The Console displays a few lines of the code, with an arrow
indicating the current line 9. Line 9 runs when I click on
“Continue Execution.”
88
Figure 4.4 Continue Execution
89
Figure 4.5 The Finished Program
To complete the program, I could add a print statement
with the answer to the riddle - the number one.
In Chapter 7, Example 1 demonstrates an infinite loop.
90
q or quit Exit Debug Mode
91
%debug
%reset
In Chapter 7, Example 1, Example 2, and Example 6
demonstrate Interactive Mode.
iPython Session
The Console prompt changes to three dots and a colon
...: to indicate you are in an iPython Session . Press enter
twice, or press Esc + Enter , to exit the iPython session.
92
In [1 ]: def myfunction(str)
...: print(str)
When the newline prompt ...: is displayed, press Shift Enter to execute the
commands.
4.8 Introspection
Introspection is the ability to determine the type of the
object at runtime. Several functions help with introspection,
as well as the “ inspect ” library.
objectname ?
dir()
help()
id()
repr()
type()
To inspect objects, we’ll execute statements in the Editor
and Console , including statements with “Instrospection”
functions that provide details about objects. The syntax
varies depending on whether you are typing in the Editor or
Console pane. The syntax is also specific to the type of
object. We’ll look at those differences in depth in Chapter 6.
In the case of data structures like Lists, Tuples, or
Dictionaries, you may want to see values for the entire List or
the value of only a particular List item.
Editor
93
Console (Python Shell)
dir()
The function dir() displays all objects in the current local
namespace , as shown in the next figure. After running the
sample “Project1.1.py ” script, the local scope changes. This
script uses the “openpyxl” library to create the ws4 object.
For example, after running the “Project1.1.py script, the dir()
function displays relevant information about the program
objects in the Console . Type the dir() command in the
Console window.
In [2 ]: dir()
95
specific to the ws4 object. The dir() function displays different
attributes depending on the type of object.
There is quite a long list of valid attributes for the ws4
object, and the next example only shows a few of the
attributes. In particular, I’m interested in what functions I
can use with the ws4 object, and I’ve highlighted the
“delete_rows ” method.
Note, if you’re using an older version of Python,
“delete_rows ” might not be available. The dir() function is
an easy way to check if a particular function or method
should work with your code.
help()
The Help() function invokes the help system for help with
a module, function, class, method, keyword, or
documentation topic. For example, when I type
help(load_workbook) in the Console window, Python
displays information specific to the method “load_workbook”
from the “openpyxl” library.
In [2]: help(load_workbook)
96
Figure 2.7 Help for load_workbook Method
97
In [3]: from inspect import signature
In [4]: print(str(signature(load_workbook)))
(filename, read_only=False, keep_vba=False, data_only=False, keep_links=True)
98
4.9 Logging
Logging is a simple way to capture debugging data. Use
logging when the output in the Console pane scrolls and is
lost because there is too much data. Logging is also useful
when you’re working out code logic, or have a live program
with user reports of erratic behavior.
This script has a logging level set to ERROR, which means
it logs errors and critical events. For a thorough look at
logging, please refer to the docs.python.org .
logging.basicConfig(format=’%(asctime)s - %(message)s’,
datefmt=’%d-%b-%y %H:%M:%S’,
filename=’test.log’,
level=logging.ERROR)
When there is an exception on line 9 in the statement
10/my_int , the Python Interpreter logs a critical error to
the test.log file.
import logging
1
logging.basicConfig(format=’%(asctime)s - %(message)s’,
2
datefmt=’%d-%b-%y %H:%M:%S’,
3
filename=’test.log’,
4
level=logging.ERROR)
5
logging.error(‘The logging level is ERROR and above.’)
6
my_int = 0
7
try :
8
10 /my_int
9
except Exception:
10
logging.critical(“my_int is %s”, my_int,
11
exc_info=True)
The first time you run the program the logfile test.log is
created. The default mode is “append.” If the log file is not
created, try restarting Spyder. This is the output in the log
file.
29-Jan-19 10:29:33 - Logging level is ERROR and above.
29-Jan-19 10:29:33 - my_int value is 0
Traceback (most recent call last):
File “/Ch 4 code/Logging/logging.py”, line 13, in <module>
10/my_int
ZeroDivisionError: division by zero
99
To disable logging, use the “disable” method with the
appropriate argument, as shown below.
logging.disable(logging.CRITICAL)
100
colors = (‘blue’, ‘red’, ‘green’)
for color in colors:
print(color)
Actual Result
When I run the code, the program halts. The Traceback
shows a ZeroDivisionError on line 65. I haven’t changed
anything in the program in several weeks. Until today the
program ran successfully. This is the code on line 65.
dailysales = (total/myday)
101
Incorrect Code
The value of “myday ” is set on line 64, as shown below.
As it happens, on the first day of the month, the statement
on line 64 evaluates to zero.
myday = (datetime.datetime.today().day-1 )
dailysales = (total/myday)
While this particular example is easy to troubleshoot,
when you have a program with external connections, it can
be a challenge to isolate the defect. With a slight
modification, I can use a variable “testmode ” as a switch to
use test values. When I want to test ‘datecalculations,’ I set
all the other conditional statements to use test data. In
effect, I remove all the other code from the equation and
only run lines 62-68.
For example, the “else” statement on line 54 sets gbp to
a value of 999.99 when testmode is “tst_datecalculations
.”
102
for your program to function. If you’re debugging an error,
be careful to keep the data that recreates the error.
In this example, I changed the code on line 13 and
created an HTML data file. Rather than connecting to a live
website, I copied the “HTML” data to a file. I also removed
unnecessary headings and tables from the HTML file.
103
5. Exceptions
104
events, we’ll look at the “raise ” command where you raise
your exception. When an object must be a certain value,
adding an “assert ” statement to trigger an exception is a
great time saver.
Finally, we’ll briefly look at the Python built-in exceptions
you’re likely to encounter when programming in Python.
• Syntax Errors
• Logic or Semantic Errors
• Runtime Errors
Syntax Errors are usually obvious, and the Spyder Editor
points out Syntax errors with a yellow triangle. Runtime
errors occur when the Python Interpreter halts and displays
an exception. I find my “Logic” errors the most difficult to
identify because the program does what I told it to, but my
initial design or logic is flawed.
Syntax
A syntax error is raised by the parser when the parser
encounters a syntax error. The Spyder Editor makes it
virtually impossible to have Syntax errors. A yellow triangle
appears to the left of the line number if there is a Syntax
error in the code.
Chapter 7 demonstrates syntax errors in Example 5, and
Examples 7-12.
105
Logic or Semantic
With a logic error, the flaw is with me. I told the program
to do something, but it’s not the outcome I want. To identify
logic errors, I find it helpful to go back to the drawing board
and look at my initial “Intended Outcome” or pseudocode.
Pseudocode is an outline of your program design in simple
terms, often written in plain English.
Runtime
The challenge with debugging runtime errors is a line (or
suite) of code runs as expected several times, and then
suddenly halts with an error. As a program runs, variable
values change. Another example of a RunTime error is when
a program takes too long to run.
While general RunTime errors are flagged as a
“RunTimeError” by the Python Interpreter, what I am
referring to as “Runtime” is the overall kind of error. The
actual Traceback message displayed in the Console may
vary, as shown in Chapter 7 in Examples 5 and Examples 7-
12.
To research a runtime error, we need to look at the
values at the moment the error occurred When looking at
values, you may have a critical variable that must be a
certain value for your code to function. Assert statements
halt the program and warn you when values are outside the
parameters you require.
Another example of a Runtime error is a chunk of code
that takes too long to run. In this case, the function “timeit”
times program execution.
• Debug Mode
• Variable Explorer
106
• Interactive Mode
• Print Statements
Chapter 7 looks at these kinds of errors in Examples 1, 4,
6, 14, 15, and 17.
• File
• Line Number
• Module
• Exception
• Exception Description
The next lines are a sample Console Traceback. I
abbreviated the file path for readability.
107
File “workbook.py”, line 289, in __getitem__
raise KeyError(“Worksheet {0} does not exist.”.format(key))
KeyError: ‘Worksheet Sheet1 does not exist.’
Don’t Be Fooled
A misleading Traceback message “NameError” could be
hiding the Traceback message you want to see. In the
Chapter 4 topic, “Variables and Objects in Memory, ” we
looked at how the Python Interpreter creates variables and
objects when you run a program or script. In this example,
there is a variable “myint” of type “int.”
myint = 57
print(myint.upper)
If the program ran and created “myint” already, the
Console Traceback message is “AttributeError” because
there is no attribute “upper” for a variable “myint.” If the
program hasn’t run and created the variable “myint,” the
Console Traceback message is “NameError.”
When the program encounters an Out of Memory error,
the Traceback exception is rarely the actual cause of the
defect.
108
5.3 Try and Except
Unhandled exceptions halt the program and display a
Traceback with an exception error. When you add “try” and
“except” statements to your code, you can control how
exceptions are handled, and prevent your program from
unexpectedly halting. In this next example with “except,” you
can see where I added custom messages.
109
try :
gbpex = float(tables2[3 ].string[:6 ])
gbp = gbp/gbpex
print(“gbp converted to USD is:”, gbp)
except TypeError:
print(“Type error when converting exchange rate”)
except ZeroDivisionError:
print(‘ZeroDivisionError where gbpex is:’, gbpex)
except Exception as exceptdetails:
print(exceptdetails, ‘gbpex is:’, gbpex)
finally :
print(“Done calculating the gbp exchange rate.”)
The finally clause at the end runs whether the try clause
has an exception or not.
5.4 Raise
At any point, you can add your own “raise” statements in
your program to raise an exception, as shown below.
raise Exception(“I broke my program.”)
5.5 Assert
When your program depends on a statement to be true,
consider adding an “assert” statement to alert you if the
statement does not evaluate to “true.” When I was
calculating KDP royalties earlier, I found the GBP exchange
rate on a web site. In order for my program to calculate GBP
royalties in USD currency, “gbpex ” must be greater than
zero.
assert gbpex > 0 , ‘gbpex must be > ‘ + str(gbpex)
Now when my program runs and “gbpex ” is not greater
than zero, an exception is raised. The Console displays a
Traceback message, as shown below.
110
AssertionError: gbpex must be > 0
ArithmeticError
ArithmeticError is the base class for built-in exceptions for
various arithmetic errors.
AssertionError
An AssertionError is raised when the assert statement
fails.
AttributeError
The AttributeError is raised on attribute assignment or
when the reference fails. When an object does not support
attribute references or attribute assignments at all, a
TypeError is raised. For example, an “int” object has no
attribute “upper.” The code below would cause an
AttributeError :
myint = 57
print(myint.upper)
Because a “string” object does have an attribute “upper,”
this code for a string is valid.
mystr = ‘age’
print(mystr.upper())
111
To view attributes of an object named “mystr ” run the
program, then type “dir(mystr) ” in the Python Console .
You must run the program for the Python Interpreter to
create the variable “mystr.” If you haven’t run the
program , the Python Interpreter displays a NameError
exception. See Chapter 7, Example 6, for a description of
debugging an AttributeError .
In Chapter 7, Example 6 demonstrates an AttributeError.
EOFError
Raised when the input() function hits the end-of-file
condition without reading any data. In Chapter 7, Example
15 demonstrates an EOFError.
FloatingPointError
Raised when a floating-point operation fails.
ImportError
When Python Interpreter has trouble loading a module,
the Interpreter raises an ImportError.
Indentation Error
The IndentationError is raised when there is an incorrect
112
indentation. In Chapter 7, Example 5 demonstrates an
IndentationError.
IndexError
An IndexError is raised when the index of a sequence is
out of range. If the index is not an integer, TypeError is
raised. The base class of an IndexError is a LookupError. See
Examples 1-2 in Chapter 7.
IOError
Starting from Python 3.3, an IOError is an OSError.
KeyError
A KeyError is raised when a key is not found in a
dictionary and is a subclass of LookupError. See Example 20.
KeyboardInterrupt
A KeyboardInterrupt is raised when the user hits the
interrupt key (Ctrl+c or delete).
LookupError
A LookupError is the base class for KeyError and
IndexError.
MemoryError
113
Raised when an operation runs out of memory.
ModuleNotFoundError
The ModuleNotFound error indicates a module could not
be located and is a subclass of ImportError.
NameError
Raised when a variable is not found in the local or global
scope. This exception occurs when an identifier is invalid or
an unknown name. For example, a misspelled identifier can
cause a NameError. The Spyder IDE would highlight a
NameError. In Chapter 7, Examples 3, 10, 13, and 22
demonstrate NameErrors.
OSError
Raised when a system operation causes a system-related
error, such as failing to find a local file on disk.
OverflowError
Raised when the result of an arithmetic operation is too
114
large to be represented. The OverflowError is a subclass of
ArithmeticError.
RecursionError
A RecursionError is derived from the base class
RuntimeError. A RecursionError is raised when the maximum
recursion depth is exceeded.
RuntimeError
Raised when an error is detected that does not fall under
any other category.
StopIteration
Raised by the next() function to indicate that there is no
further item to be returned by the iterator.
SyntaxError
Raised by the parser when a syntax error is encountered.
The Spyder Editor makes it virtually impossible to have
Syntax errors. A yellow triangle appears to the left of the line
number if there is a Syntax error in the code.
TabError
Raised when indentation contains an inconsistent use of
tabs and spaces. The TabError is a subclass of
IndentationError.
115
SystemError
Raised when the interpreter detects an internal error.
SystemExit
Raised by the sys.exit() function.
TypeError
Raised when a function or operation is applied to an
object of an incorrect type. Attempting to perform an
operation on an incorrect object type.
ValueError
A ValueError is raised when a function gets an argument
of correct type but improper value. For example, a datetime
object considers a time value for seconds < 60 or a month
between 1 and 12 to be valid. A datetime month value of 13
creates an exception, and the Python Interpreter displays a
ValueError. The syntax below is invalid for a datetime object:
d1 = datetime( 1999, 13, 31)
ZeroDivisionError
Raised when the second argument of a division or modulo
operation is zero. The ZeroDivisionError is a subclass of
ArithmeticError.
116
6. Try This
117
To provide the missing piece of the debugging puzzle, I’m
going to take some time in this Chapter to break down the
debugging process into a reusable format. I’ll cover some
common issues. Unfortunately, my issue list isn’t going to be
all-inclusive, but I hope it kickstarts your debugging
experience.
While an odd chapter title, “Try This,” is a fitting name.
When I was learning to program, I would share my dilemmas
with a good friend. He would say, “Try this...” and offer a few
suggestions. That little nudge in the right direction was a
godsend that helped me find my way. I’m not sure if I can
create that experience for you, but I’m going to try.
As we work through the next sections, you’ll notice a
common theme, where we look at these topics in different
contexts.
• Object Values
• Types of Objects
• Length of Objects
• Passing Arguments to Functions or Methods.
• The Return Object of a Function
We’ll look at the common objects outlined below. This list
of objects isn’t every possible Python object, but I think
these are enough to get you started.
• Strings and Numbers
• Tuples
• Lists
• Dictionaries
118
It can be exasperating when you have a runtime or logic
error and have no idea where to start debugging. The
suggestions in this chapter may help you get started
debugging your program.
119
Editor window. When I run the program, the output of the
print statement is shown in the Console pane. The Console
is the Python Shell.
A String Identifier: mystring
Value: purple peanuts
Reference: Chapter 4 - Add Print Statements
1
mystring = “purple peanuts”
2
print(mystring)
3
In [1 ]: runfile(‘C:/SampleScript.py’, wdir=’C:’)
purple peanuts
120
mystring = “purple peanuts”
A String Identifier: mystring
Value: purple peanuts
Reference: Chapter 4 - Interactive Mode
121
In [1 ]: runfile(‘C:/SampleScript.py’, wdir=’C:’)
(‘Apple’, ‘Orange’, ‘Watermelon’)
In [1 ]: runfile(‘C:/SampleScript.py’, wdir=’C:’)
Apple
122
next line in the Console .
Object Type Identifier Value
In [2 ]: mytuple
Out[2 ]: (‘Apple’, ‘Orange’, ‘Watermelon’)
123
Print All List Item Values
In this example, I print out all List item values to the
Console pane.
All Items of the List
Identifier: mylist
Value: Name: Soda, Water, Coffee
Reference: Chapter 4 - Add Print Statements
In [1 ]: runfile(‘C:/SampleScript.py’, dir=’C:’)
(‘Soda’, ‘Water’, ‘Coffee’)
124
In [1 ]: runfile(‘C:/SampleScript.py’, wdir=’C:’)
soda
Figure
6.1
125
All Items in the List
Identifier: mylist
Value: Name: Soda, Water, Coffee
Reference: Chapter 4 - Interactive Mode
126
Objects and Dictionary Key-Pair values. To create a
Dictionary, use this syntax:
1 mydictionary = { ‘Name’ :
2 ‘Zimmerman’ ,
3 ‘Grade’ : ‘A’ ,
4 ‘Course’ : ‘Python Programming’
5 }
print(dictionary[‘Name’])
In [1 ]: runfile(‘C:/SampleScript.py’, wdir=’C:’)
Water
128
In [2 ]: mydictionary[‘Grade’]
Out[2 ]: ‘A’
129
Value of None or
Whitespace?
When importing external data into Python data
structures, it is not uncommon to have items with a value of
“None” or unexpected whitespace. For example, if you import
an Excel worksheet with empty cells, those List items have a
value of “None.” Also, sometimes strings are null or equal to
“”.
Functions with return values can also sometimes return
“None.” The value “None” is returned when you don’t have a
return value for all paths in the function, as explained in the
Chapter 3 topic, “Function Return Values .” Example 17 in
Chapter 7 also illustrates a function that returns “None.”
The “None” value causes problems when working with
functions that expect a particular type or value for an object.
For example, the DateTime library function “.strftime”
expects an object of type “datetime”, “time”, or “date.” If the
object has a value of “None,” the Python interpreter displays
an error, as shown in Chapter 7, Example 20 .
Sadly, this is also one way Divide by Zero errors happen
in a program. When you convert an item in a data structure
from a string to an “int,” an item with a value of “None”
becomes a zero. The Divide by Zero error is shown in the
Examples Chapter, Example 24 and 17 , and includes a
sample “if statement” to test for a “None” value.
Whitepsace
Another cause of unexpected consequences is
whitespace. There may be a tab, line return, or some other
character that impacts a search or comparison. These
130
functions are useful for removing those unseen characters.
lstrip() Remove left whitepspace characters.
rstrip() Remove right whitespace characters.
strip() Remove whitespace characters from both sides.
131
number, string or data structure len(mytuple)
len(mylist)
len(mydictionary)
a Tuple item len(mytuple[0])
a List item len(mylist[0])
a Dictionary item len(mydictionary(‘Name’]
132
below. Chapter 7, Example 20, also illustrates this syntax
from PEP 362 . The inspect library can also display the
DocString mentioned in the topic “Classes” in Chapter 3 .
133
In [3]: from inspect import signature
In [4]: print(str(signature(load_workbook)))
(filename, read_only=False, keep_vba=False, data_only=False, keep_links=True)
134
7. Examples
135
25 There is a mistake in a math calculation Logic Error
26 Assigning datetime value causes ValueError ValueError Runtime
Intended Outcome
There are two Lists in this program, “meals” and “fruits.”
I want the program to loop through each list and print the
items in order.
136
Actual Result
The Console output shows the print statement on line 6
repeats with the first item in the List.
137
Incorrect Code
This is the Example 1 Code before any changes. Can you
spot the three areas we need to fix? We’ll look at each error
in Examples 1-3.
meals = [‘breakfast’, ‘lunch’, ‘snack’, ‘dinner’]
fruits = [‘apple’, ‘orange’, ‘grape’]
i=0
while i < 4 :
j=0
print(“my meal is: “, meals[i])
while j < 4 :
print(“My choice of fruit is: “, fruits[i])
j=j+1
i=i+1
Debugging Experiment
In this example, when I run the program, it loops
continuously. Next, I use Debug Mode to research what is
happening.
138
3. The Console prompt changes to ipdb> to indicate you are
in Debug Mode. In the Console , type “ s ” to step
through the program. The Python Interpreter moves to
the next line.
Type “ s ” a few times, and you’ll notice the program loops
back to line 4. Variable Explorer shows the value of “ i ” is
0 and is not changing as the program runs.
4. In the earlier figure, the print statement on line 6 was
repeatedly output to the Console , indicating that the
“while loop” on line 4 is looping continuously. I suspect
that my counter “i” is not incremented properly on line
10.
In the Console, pane, type “ q ” to quit Debug Mode . The
next topic outlines the change to resolve this issue.
139
Good Code
meals = [‘breakfast’, ‘lunch’, ‘snack’, ‘dinner’]
fruits = [‘apple’, ‘orange’, ‘grape’]
i=0
while i < 4 :
j=0
print(“my meal is: “, meals[i])
while j < 4 :
print(“My choice of fruit is: “, fruits[i])
j=j+1
i=i+1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Add Print Statements
Chapter 4 - Interactive Mode
Chapter 4 - Debug Mode Variable Explorer
Chapter 4 - Infinite Loop
Chapter 5 - Traceback
Chapter 5 - IndentationError
Chapter 5 - IndexError
Chapter 6 - Check Object Type
Intended Outcome
140
There are two Lists in this program, “meals” and “fruits.”
I want the program to loop through each list and print the
items.
Actual Result
The print statement on line 8 fruits[i] causes an
IndexError.
Incorrect Code
Example 2 code before any changes follows.
1 meals = [‘breakfast’ , ‘lunch’ , ‘snack’ , ‘dinner’ ]
2 fruits = [‘apple’ , ‘orange’ , ‘grape’ ]
3 i=0
4 while i < 4 :
5 j=0
6 print(“my meal is: “, meals[i])
7 while j < 4 :
8 print(“My choice of fruit is: “, fruits[i])
9 j=j+1
10 i=i+1
Debugging Steps
In this Example the program halts. I use Debug Mode to
research what is happening.
141
2. Type %debug In the Console, pane to start Debug Mode.
The Console prompt changes to ipdb> .
3. Type fruits[3] In the Console, pane. The Variable Explorer
shows j has a value of 3, so fruits[i] evaluates to
fruits[3]. The message “IndexError: list index out of
range” is displayed.
142
Figure 7.1 Corrected Code
143
Good Code
1 meals = [‘breakfast’ , ‘lunch’ , ‘snack’ , ‘dinner’ ]
2 fruits = [‘apple’ , ‘orange’ , ‘grape’ ]
3 i=0
4 while i < 4 :
5 j=0
6 print(“my meal is: “, meals[i])
7 while j < 3:
8 print(“My choice of fruit is: “, fruits[j])
9 j=j+1
10 i=i+1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Debug Mode
Chapter 4 - Interactive Mode
Chapter 4 - Debug Mode Variable Explorer
Chapter 5 - Traceback
Chapter 5 - IndexError
Chapter 6 - Check Object Type
Chapter 6 - Check Length of Object
144
Intended Outcome
The program should print a list of fruits for each meal.
Actual Result
The program halts with an IndexError exception.
145
Incorrect Code
Example 3 code before any changes follows.
meals = [‘breakfast’, ‘lunch’, ‘snack’, ‘dinner’]
fruits = [‘apple’, ‘orange’, ‘grape’]
i=0
while i < 4 :
j=0
print(“my meal is: “, meals[i])
while j < 3:
print(“My choice of fruit is: “, fruits[i])
print(“j is: “, j)
j=j+1
i=i+1
Debugging Steps
1. When I run the program, the Python Interpreter halts
with an error. The Traceback shows the IndexError was
caused by line 8.
146
At this point, I just typed a statement in the Console , so I
don’t need to exit Debug Mode . Instead, I’ll update my
script in the Editor pane to resolve the issue.
147
Good Code
meals = [‘breakfast’, ‘lunch’, ‘snack’, ‘dinner’]
fruits = [‘apple’, ‘orange’, ‘grape’]
i=0
while i < 4 :
j=0
print(“my meal is: “, meals[i])
while j < 3:
print(“My choice of fruit is: “, fruits[j])
print(“j is: “, j)
j=j+1
i=i+1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 3 - IndentationError
Chapter 4 - Debug Mode
Chapter 4 - Debug Mode Variable Explorer
Chapter 6 - Check Object Type
Intended Outcome
Print “mylist” items to the Console.
148
Actual Result
The Console output shows the print statement on line 4
repeats with the first item in the List.
149
Incorrect Code
This is the Example 4 code before any changes.
mylist = [‘soda’, ‘water’, ‘coffee’]
i=0
while i < 3:
print(mylist[i])
i =+ 1
Debugging Steps
1. Run the program. The program runs endlessly. The
program is caught in an an infinite loop. In the Console ,
the Python Interpreter repeatedly outputs the print
statement from line 4.
2. To stop the program, in the Consoles menu, I select
“Restart kernel.”
Double click twice on line 4 to add a breakpoint. Select
“Debug File” on the menu, as shown below.
3. The Console prompt changes to ipdb> to indicate you are
in Debug Mode. In the Console , type “ s ” to step
through the program. The Python Interpreter moves to
the next line.
Type “ s ” a few times, and you’ll notice the program loops
back to line 3. Variable Explorer shows the value of “ i ” is
0 and is not changing as the program runs.
150
Good Code
mylist = [‘soda’, ‘water’, ‘coffee’]
i=0
while i < 3:
print(mylist[i])
i += 1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Debug Mode
Chapter 4 - Debug Mode - Variable Explorer
Chapter 4 - Infinite Loop
Intended Outcome
Print a list of numbers.
Actual Result
When I run the program, it halts with an
IndentationError.
151
Incorrect Code
This is the Example 5 code before any changes.
wadofcash = [111, 222, 333, 444 ]
i=0
x=3
while i <= x:
print(wadofcash[i])
i=i+1
Debugging Steps
Spyder displays a yellow warning triangle next to the
print statement on line 6. When I hover my mouse over the
triangle, a pop-up message is displayed, as shown below.
If I run the program, the Console displays an
IndentationError .
152
Good Code
wadofcash = [111, 222, 333, 444 ]
i=0
x=3
while i <= x:
print(wadofcash[i])
i=i+1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 -Help()
Chapter 5 - Traceback
Chapter 5 - IndentationError
Intended Outcome
My intention was for the code to open an Excel file and
print each column 2 value as the program iterates through
the rows.
Actual Result
153
The program halted with an “AttributeError” exception
when run with the Python 2.7 Interpreter. The program runs
fine on my Python 3 environment. This AttributeError
indicates the Python Interpreter doesn’t recognize the line 8
syntax.
Line 8 is calling a method in a class. In the discussion of
Classes in Chapter 3, we created an instance of a class. Valid
attribute names of a class include both “data attributes ”
and “methods .” Python objects have attributes that are
referenced with the dot notation.
154
Incorrect Code
This is the Example 6 code before any changes.
from openpyxl import load_workbook
wb1 = load_workbook(‘Before.xlsx’, data_only=True)
ws1 = wb1[“ExportedData”]
bfr = 2
while bfr <= ws1.max_row:
bfritem = ws1.cell(bfr, 2 ).value
print(bfritem)
bfr = bfr + 1
Debugging Experiment
In this example, when I run the program, the Python
Interpreter prints an “AttributeError” to the Console. I use
Help to research what is happening.
155
on the object.
156
Good Code
from openpyxl import load_workbook
bfritem = ws1.cell(row=bfr, column=2 ).value
wb1 = load_workbook(‘Before.xlsx’, data_only=True)
ws1 = wb1[“ExportedData”]
bfr = 2
while bfr <= ws1.max_row:
bfritem = ws1.cell(row=bfr, column=2 ).value
print(bfritem)
bfr = bfr + 1
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 3 - Attributes
Chapter 3 - Methods
Chapter 4 - Help()
Chapter 4 - Interactive Mode
Chapter 5 - Traceback
Chapter 5 - AttributeError
Chapter 6 - Check Arguments
Intended Outcome
While writing a program, I want to have a block of code
that does nothing. At some point, I intend to add logic.
157
Actual Result
The Python Interpreter has an IndentationError
exception.
Incorrect Code
This is the Example 7 code before any changes.
for mynum in [157, 19, 56 ]:
if mynum == 157 :
else:
print(‘Happy birthday, you are’, mynum)
Debugging Steps
The Console shows an IndentationError on line 3. As is
often the case, the actual error is the line above.
158
Good Code
for mynum in [157, 19, 56 ]:
if mynum == 157 :
pass
else:
print(‘Happy birthday, you are’, mynum)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - Traceback
Chapter 5 - RuntimeError
Chapter 5 - SyntaxError
Intended Outcome
On line 3, I want to calculate projected sales.
Actual Result
When I run the program, the Console displays a
Syntaxerror in line 3.
159
Incorrect Code
This is the Example 8 code before any changes.
sales = 150.00
days = 31
projectedsales = (sales/days)*31 )
Debugging Steps
The Editor displays a red x to the right of line 3,
indicating the parser identified invalid syntax. When I hover
my mouse over the parentheses on that line, the paired
parentheses are highlighted in green.
160
Good Code
sales = 150.00
days = 31
projectedsales = ((sales/days)*31 )
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - SyntaxError
Intended Outcome
Print mylist items to the Console.
Actual Result
When I run the program, there is a SyntaxError.
Incorrect Code
This is the Example 9 code before any changes.
mylist = [‘soda’, ‘water’, ‘coffee’]
for i in range(3)
161
print(mylist[i])
Debugging Steps
The Editor has a red x by line 32 and a yellow triangle
to the left of line 3. When I hover over the yellow triangle, a
pop-up message is displayed, “unexpected indentation.”
162
Good Code
mylist = [‘soda’, ‘water’, ‘coffee’]
for i in range(3) :
print(mylist[i])
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - SyntaxError
Intended Outcome
Print mylist items to the Console.
Actual Result
When I run the program, the Console displays a
NameError.
Incorrect Code
163
In this example, I changed the case on the variable
“myList” with the intention of causing a NameError.
Debugging Steps
1. To clear memory (the namespace), in the Consoles
menu, select “Restart kernel.” You could also type %reset
in the Console.
2. When I run the program, the Console displays a
NameError on line 3.
164
Good Code
mylist = [‘soda’, ‘water’, ‘coffee’]
for i in range(3) :
print(mylist[i])
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - NameError
Intended Outcome
This code creates a new function that adds two numbers
together.
Actual Result
The Editor displays a red “x” to the left of line 1. When I
run the program, the Console Traceback says there is a
SyntaxError on line 1.
165
Figure 7.3 Function with Error
Incorrect Code
This is the Example 11 code before any changes.
myfunction(x, y):
return x+y
Debugging Steps
When looking at line 1, I see that I left off the keyword
“def.” I could also search online for the Python
documentation on defining a function.
Good Code
def myfunction(x, y):
return x+y
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 5 - Traceback
Chapter 5 - SyntaxError
Intended Outcome
This code creates a string variable.
Actual Result
The program halts with a SyntaxError.
167
Incorrect Code
This is the Example 12 code before any changes.
my$str = ‘hello’
print(my$str)
Debugging Steps
The Editor has a red “x” to the left of line 1, indicating
there is a syntax error in my assignment statement.
Normally, the Editor highlights functions and methods in
purple, and variables are black. The formatting is different
because the Editor is unable to interpret the code.
When I run the program, the Console displays an arrow
pointing to the invalid character in my string name.
168
Good Code
mystr = ‘hello’
print(mystr)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 4 - Debug Mode
Chapter 4 - Interactive Mode
Chapter 5 - NameError
Chapter 5 - SyntaxError
Intended Outcome
Line two calculates profit using the “royalties” variable.
Actual Result
The Editor has a yellow triangle to the left of line 2. When
I run the program the Traceback shows a NameError.
169
Incorrect Code
This is the Example 13 code before any changes.
royalties = 30
profit = royaltie - 2
Debugging Steps
In the Editor, if I click on the variable name, the Editor
highlights all instances of the variable throughout the code. I
assign 300 to the “royalties” variable in line 1. The variable
name is misspelled on line 2.
170
Good Code
royalties = 30
profit = royalties - 2
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 5 - Traceback
Chapter 5 - NameError
Ex 7.14 FileNotFound
Description: While reading a file, the Console halted
with an error “FileNotFoundError.” In this example, factors
outside your control impact your program.
Intended Outcome
This program opens a text file and prints the contents in
the Console.
Actual Result
The Console displays a “FileNotFoundError.”
Incorrect Code
This is the Example 14 code before any changes.
171
file = open(‘file.txt’, ‘r’)
print(file.read())
Debugging Steps
The “FileNotFoundError” has a base class of “IOError.” I
want to check the filename in my OS directory.
172
Good Code
file = open(‘file.txt’, ‘r’)
print(file.read())
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Interactive Mode
Chapter 5 - Traceback
Chapter 5 - RuntimeError
Chapter 5 - OSError (IOError)
Intended Outcome
Print the total when adding two numbers.
Actual Result
When I run the program, the Console Traceback message
is a TypeError. The code uses “try” and “except” to provide
exception details in the Traceback message. In this example,
the code prints a custom message when there is a TypeError.
The last line prints a custom message if there is another type
173
of Exception.
174
Incorrect Code
This is the Example 15 code before any changes.
eur = ‘euro’
gbp = 8
usd = 3.45
try :
mymoney = eur + usd
print(mymoney)
except TypeError:
print(‘Type error when adding’)
except Exception as strmsg:
print(strmsg)
Debugging Steps
Add the variable information to my print statement and
run the program again.
print(‘Type error when adding; eur’, eur, ‘; usd’, usd)
The Console Traceback shows the variable values. After
reviewing I realize I used “eur” which is a string, and I meant
to use “gbp.”
175
use gbp + usd .
176
Good Code
eur = ‘euro’
gbp = 8
usd = 3.45
try :
mymoney = gbp + usd
print(mymoney)
except TypeError:
print(‘Type error when adding; gbp’, gbp, ‘; usd’, usd)
except Exception as strmsg:
print(strmsg)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Print Statements
Chapter 4 - Type()
Chapter 5 - Traceback
Chapter 5 - TypeError
Ex 7.16 Misspelled
Keyword
Description: A misspelled keyword causes a
SyntaxError. This is similar to Example 13 where a variable
name was misspelled causing a NameError.
Intended Outcome
An if-else statement prints a message to the Console.
177
Actual Result
The Editor has a red “x” next to line 4. When I run the
program it halts with a “SyntaxError.”
Incorrect Code
This is the Example 16 code before any changes.
if 4 < 5:
pass
esle:
print(“Python rocks”)
Debugging Steps
There is a typographical error on line3.
178
Good Code
if 4 < 5:
pass
else:
print(“Python rocks”)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - Traceback
Chapter 5 - NameError
Chapter 5 - SyntaxError
Intended Outcome
My calculation using the “mymath” function return value
prints the result to the Console.
Actual Result
When “i” is 3, the Traceback In the Console , displays a
TypeError .
179
Incorrect Code
This is the Example 17 code before any changes.
def mymath (i=5 , j=200 ):
if i > 3 :
return i*j
if i < 3 :
return j/i
result = mymath(3 , 100 )
print(result/10 )
Debugging Steps
This program works as expected when “i” is any number
except 3.
1. To identify what type the function returns, I use the
type() function in the Console.
In[2] : type(mymath(3,100 ))
Ou t[2]: NoneType
The function returns “None” when “i” is 3.
2. In the Console, I call the “mymath” function again where
“i” is 4. Now the type is “int.” This means that there is a
path through the “mymath” function without a return
value.
In Chapter 3, we looked at a function that did not have a
return value for all paths . For this example, I’m not
going to change the “mymath” function. Instead, I add
logic to my program to handle a “None” value.
180
Good Code
def mymath (i=5 , j=200 ):
if i > 3 :
return i*j
if i < 3 :
return j/i
result = mymath(3 , 100 )
if result is not None:
print(result/10 )
else :
print(“result is None” )
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 3 - Function Returns None
Chapter 4 - Interactive Mode
Chapter 5 - Traceback
Chapter 6 - Check Object Type
Chapter 6 - Value is None
Intended Outcome
Using the math library, I would like to use a cube
method.
181
Actual Result
When I run the code the Console displays the message
“AttributeError :module ‘math’ has no attribute ‘cube’.”
Incorrect Code
This is the Example 19 code before any changes.
import math
mynum = (.3 , .7 )
mytotal = math.fsum(mynum)
mycube = math.cube(3 )
print(mytotal)
Debugging Steps
I need to see what functions or methods are available for
the math library. In the Editor, after I type “math.” I pause
for a moment. A pop-up opens with available methods, as
shown below.
182
Good Code
import math
mynum = (.3 , .7 )
mytotal = math.fsum(mynum)
mycube = 3 *3 *3
print(mytotal)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 3 - Tuple
Chapter 4 - Debug Mode
Chapter 4 - Interactive Mode
Chapter 5 - Traceback
Chapter 5 - NameError
Intended Outcome
Using the “matplotlib” library I want to plot a chart.
Actual Result
When I run the code, the Console displays
ModuleNotFoundError.
183
Incorrect Code
This is the Example 19 code before any changes.
import matplotlibpyplot as plot
plt.plot([1 , 2 , 3 , 4 ], [25 , 30 , 29 , 31 ])
plt.ylabel(‘age’)
plt.xlabel(‘participants’)
plt.show()
Debugging Steps
I am trying to use the library “matplotlib” plot function,
but am unsure how to import the library. When I search the
Internet for “import matplotlib” I find the correct syntax. In
the help pane, I could search for “mathploglib.pyplot” for
additional details.
Good Code
import matplotlib.pyplot as plot
184
plot.plot([1 , 2 , 3 , 4 ], [25 , 30 , 29 , 31 ])
plot.ylabel(‘age’)
plot.xlabel(‘participants’)
plot.show()
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Help()
Chapter 5 - Traceback
Chapter 5 - ModuleNotFound
Intended Outcome
This program works with an Excel file and formats cells.
Line 11 loops through the rows, and line 12 loops through
the cells of each row. In line 13 I want to set “wrap text” for
the cells.
185
Figure 7.6 20_KeyError.py Script
Actual Result
The program halts and the Traceback In the Console,
displays this error:
KeyError: ‘Worksheet Sheet1 does not exist.’:
186
Incorrect Code
This is the Example 20 code before any changes.
# 20_KeyError.py
from openpyxl import load_workbook, styles
wb = load_workbook(‘before.xlsx’, data_only=True)
ws = wb[“Sheet1”]
ft = styles.Fontt(color=’4F81BD’, bold=True)
ws[‘A1’].font = ft
ws.cell(row=1, column=1).value = ‘Heading 1’
ws.column_dimensions[‘A’].width = 12
for row in ws.iter_rows():
for cell in row:
print(“Looping through data”)
Debugging Experiment
In this Example, when I run the program the program
halts. I use Debug Mode to research what is happening.
187
ipdb> u
> /20_KeyError.py (4)<module> ()
2 from openpyxl import load_workbook, styles
3 wb = load_workbook(‘before.xlsx’ , data_only=True )
----> 4 ws = wb[“Sheet1” ]
5
6 ft = styles.Fontt(color=’4F81BD’, bold=True)
Line 4 is trying to reference “Sheet1.” Although it’s not
readily apparent, this KeyError indicates this is a
Dictionary key. In the Console, pane, type “ q ” to quit
Debug Mode.
5. Now I need a method to find the sheetnames for the “ wb
” object. In the Console , I use the help command, as
shown below.
188
Figure 7.9 The sheetnames Method
189
Good Code
In the Editor, I updated line 4 with the sheetname
“ExportedData,” as shown below.
# 20_CORRECT_KeyError.py
from openpyxl import load_workbook, styles
wb = load_workbook(‘before.xlsx’, data_only=True)
ws = wb[“ExportedData”]
ft = styles.Fontt(color=’4F81BD’, bold=True)
ws[‘A1’].font = ft
ws.cell(row=1, column=1).value = ‘Heading 1’
ws.column_dimensions[‘A’].width = 12
for row in ws.iter_rows():
for cell in row:
print(“Looping through data”)
Additional Troubleshooting
In step 4, I wanted more information on
“load_workbook .” The signature function from the Chapter
6 topic, “The Function Call Signature ” would be perfect for
this purpose. With Python v3.x the “signature” lists each
parameter accepted by a function. In the Console, import the
module and print the signature for the object, as shown
below.
In [3]: from inspect import signature
In [4]: print(str(signature(load_workbook)))
(filename, read_only=False, keep_vba=False, data_only=False, keep_links=True)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 3 - Dictionary
Chapter 3 - Tuple
190
Chapter 4 - Debug Mode
Chapter 4 - Help()
Chapter 5 - Traceback
Chapter 5 - KeyError
Ex 7.21 Incorrect
Argument Type
Description: A function argument is an incorrect type
causing a ValueError.
Intended Outcome
The program asks for a month as input. The int() function
converts the data to an integer so I can use it in a
calculation. The print() function outputs the value to the
Console .
Actual Result
When the program runs, if I enter a string for input, a
ValueError is displayed in the Console . A ValueError is raised
when a function gets an argument of correct type but
improper value.
Incorrect Code
This is the Example 21 code before any changes.
birthmo = int(input(‘what month were you born?’))
monthstogo = 12 - birthmo
print(monthstogo, “months until your birthday”)
191
Debugging Steps
The Traceback shows the program fails on line 1, which
means the variable “birthmo” is not created in memory, and
is not shown in Variable Explorer.
The Traceback message shows ValueError: invalid literal
for int() with base 10: ‘June.’ The string input ‘June’ causes a
ValueError when the int() function tries to convert the string
to an integer.
192
Good Code
try:
birthmo = int(input(‘what month were you born?’))
monthstogo = 12 - birthmo
print(monthstogo, “months until your birthday”)
except ValueError:
print(‘enter a number, no letters’)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 5 - Traceback
Chapter 5 - Try and Except
Chapter 5 - ValueError
Chapter 6 - Check Object Type
Intended Outcome
Using the “matplotlib” library I want to plot a chart.
Actual Result
When I run the code, the Console displays a NameError
and highlights line 2.
193
Incorrect Code
This is the Example 22 code before any changes.
import matplotlib.pyplot as plot
plt.plot([1 , 2 , 3 , 4 ], [25 , 30 , 29 , 31 ])
plt.ylabel(‘age’)
plt.xlabel(‘participants’)
plt.show()
Debugging Steps
The NameError indicates the object can’t be found. When
I imported the library on line 1, I used “plot,” and on the
other lines I used “plt.”
Good Code
import matplotlib.pyplot as plt
plt.plot([1 , 2 , 3 , 4 ], [25 , 30 , 29 , 31 ])
plt.ylabel(‘age’)
plt.xlabel(‘participants’)
plt.show()
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 5 - NameError
194
Ex 7.23 Value Error
Descriptio n: Invalid data passed to method causing
ValueError.
Intended Outcome
I want to remove one item from my list.
Actual Result
When the program runs it halts with a ValueError on line
3. A ValueError is raised when a function or method gets an
argument of correct type but improper value.
ValueError: list.remove(x): x not in list
Incorrect Code
This is the Example 23 code before any changes.
fruits = [‘apple’, ‘orange’, ‘grape’]
myfruit = 2
fruits.remove(myfruit)
Debugging Steps
Line 3 uses the “remove” method. I would like to inspect
the list object to see what methods are available.
195
“remove” and press Cntrl + I. The Help pane displays the
same information on the remove method.
Good Code
fruits = [‘apple’, ‘orange’, ‘grape’]
myfruit = ‘orange’
fruits.remove(myfruit)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Interactive Mode
Chapter 4 - Help()
Chapter 5 - ValueError
Chapter 5 - RuntimeError
Intended Outcome
The program retrieves the current GBP exchange rate,
and then converts “gbp” to the equivalent USD value.
Actual Result
When the program runs, a ZeroDivisionError from line 7
is displayed in the Console
197
Incorrect Code
This is the Example 24 code before any changes.
from bs4 import BeautifulSoup
from urllib.request import urlopen
usd, gbp, gbpex = 10.0 , 20.0 , 0.00
html2 = urlopen(‘https://usd.fxexchangerate.com’)
soup2 = BeautifulSoup(html2, ‘lxml’)
tables2 = soup2.findChildren(‘td’)
gbp = gbp/gbpex
print(“gbp converted to USD is:”, gbp)
Debugging Steps
1. Variable Explorer shows the value of “gbpex” is zero.
In this example, I omitted the line to retrieve the GBP
exchange rate.
198
Good Code
from bs4 import BeautifulSoup
from urllib.request import urlopen
usd, gbp, gbpex = 10.0 , 20.0 , 0.00
html2 = urlopen(‘https://usd.fxexchangerate.com’)
soup2 = BeautifulSoup(html2, ‘lxml’)
tables2 = soup2.findChildren(‘td’)
try :
gbpex = float(tables2[3 ].string[:6 ])
gbp = gbp/gbpex
print(“gbp converted to USD is:”, gbp)
except ZeroDivisionError:
print(‘ZeroDivisionError where gbpex is:’, gbpex)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Interactive Mode
Chapter 4 - Debug Mode - Variable Explorer
Chapter 4 - Logging
Chapter 5 - Traceback
Chapter 5 - ZeroDivisionError
Intended Outcome
The math calculation should return 10.
199
Actual Result
The calculation returns 40 instead of 10.
Incorrect Code
This is the Example 25 code before any changes.
myval = 60.0 /3.0 * 2
print(“myval is:”, myval)
Debugging Steps
To ensure multiplication occurs before the division, I add
parentheses to my code.
Good Code
myval = 60.0 /(3.0 * 2)
print(“myval is:”, myval)
Ex 7.26 ValueError
Assigning Date
Description: Operation on incompatible types.
ValueError when assigning a datetime object.
200
Intended Outcome
After creating a datetime object with a date of
12/31/1999, I want to print the value to the Console.
Actual Result
The program halts with a ValueError exception. The
Traceback indicates the error is on line 3.
Incorrect Code
This is the Example 26 code before any changes.
from datetime import datetime
d1 = datetime.strftime(datetime(1999 , 13 , 31 ), ‘%Y-%m-%d’)
Debugging Steps
At a glance I can see that while my intentions were good,
I made a mistake on line 3. It’s obvious there is no month
“13” and the statement on line 3 is invalid. The ValueError In
the Console , also states the “month must be in 1..12.”
When the cause of the ValueError is not obvious, you
could use the Help pane, or search the Internet, to find
correct arguments for a function or method.
201
Good Code
from datetime import datetime
d1 = datetime.strftime(datetime(1999 , 12 , 31 ), ‘%Y-%m-%d’)
Reference
These topics from previous chapters are a good reference
for this example.
Chapter 4 - Interactive Mode
Chapter 5 - Traceback
Chapter 5 - ValueError
Chapter 6 - Check Arguments
Chapter 6 - Check Function Return Objects
202
Appendix - URLs
Arguments
The Python design and glossary entries for arguments are
shown in this section. Also see Calls, Functions, and
Parameters.
The design of keyword only arguments is covered in PEP
3102:
https://www.python.org/dev/peps/pep-3102/
The Python glossary entry for arguments:
https://docs.python.org/3/glossary.html#term-argument
Python terminology on arguments and parameters:
https://docs.python.org/3.3/library/inspect.html#inspect.Parameter
The difference between Arguments and Parameters:
https://docs.python.org/3/faq/programming.html#faq-
argument-vs-parameter
Assert
The Python reference for assert statements is available on
the docs.ptyhon.org website.
https://docs.python.org/3/reference/simple_stmts.html#the-
assert-statement
203
Attributes
The Python glossary entry for “attributes ” is available on the
docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-attribute
Built-in Functions
The Python reference for built-in functions is available on the
docs.ptyhon.org website.
https://docs.python.org/3/library/functions.html
Calls
The Python reference documentation explains “calling”
functions and methods, and is available on the
docs.ptyhon.org website.
https://docs.python.org/3/reference/expressions.html#calls
Classes
Information on Python Classes is available on the
docs.ptyhon.org website.
204
Comparisons
The following link is the Python reference on comparisons.
https://docs.python.org/3/reference/expressions.html#comparisons
Containers
The docs.ptyhon.org website explains “containers” in the
9.9 section “Container Objects and Iterators.” The section 3.1
topic “Objects, values and types” also explains that objects
that contain references to other objects are containers.
Examples of containers are tuples, lists and dictionaries.
https://docs.python.org/3.8/reference/datamodel.html#index-
3
The 3.1 topic “objects, values, and types” explains that
“container” objects contain references to other objects. This
“Data Model” reference is available on the docs.ptyhon.org
website.
https://docs.python.org/3/reference/datamodel.html#index-
3
doctest
The docs.ptyhon.org website has details on using the
doctest module to search and validate examples in
docstrings.
https://docs.python.org/3/library/doctest.html?
highlight=doctest
Interactive Python examples are also available. These
examples include reading in a text file
205
Functions
The Python reference documentation explains “functions,”
and is available on the docs.ptyhon.org website.
https://docs.python.org/3/reference/compound_stmts.html#function
The Python tutorial for “Defining Functions” is available on
the docs.ptyhon.org website.
https://docs.python.org/3/tutorial/controlflow.html#defining-
functions
https://docs.python.org/3/reference/compound_stmts.html#function-
definitions
The difference between function parameters and arguments
is explained in the FAQs available on the docs.ptyhon.org
website.
https://docs.python.org/3/faq/programming.html#faq-
argument-vs-parameter
The Python glossary entry for “functions” is available on the
docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-function
Glossary
The official Python glossary is available on the
docs.ptyhon.org website
https://docs.python.org/3/glossary.html
The if Statement
Information on the if statement is available on the
docs.ptyhon.org website
206
https://docs.python.org/3/reference/compound_stmts.html#the-
if-statement
Immutable
The Python glossary explains the concept of “immutable”
objects, and is available on the docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-immutable
Inspect
The Python reference for the “inspect” library is available on
the docs.ptyhon.org website.
https://docs.python.org/3/library/inspect.html
Interactive Mode
Interactive Mode in the Console is explained on the
ipython.readthedocs website.
https://ipython.readthedocs.io/en/stable/interactive/reference.html
.
207
Logging
The Python docs for the “logging library” are available on the
docs.ptyhon.org website.
https://docs.python.org/3/library/logging.html#logging.basicConfig
https://docs.python.org/3.8/howto/logging.html
https://docs.python.org/3/library/logging.html
Magic Functions
Functions that begin with the percent symbol are magic
functions or magic commands and are sometimes
implemented in a iPython kernel. Read more about magic
functions at
https://ipython.readthedocs.io/en/stable/interactive/reference.html
.
Methods
The Python glossary explains “methods,” and is available on
the docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-method
Objects
The Python glossary explains “objects,” and is available on
the docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-object
Objects like data attributes have value or “state,” and objects
like methods have “defined behavior.”
208
The 3.1 topic “objects, values, and types” in the “Data Model”
reference is available on the docs.ptyhon.org website.
https://docs.python.org/3/reference/datamodel.html#index-
3
Parameters
The Python glossary explains “parameters,” and is available
on the docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-parameter
There is information on arguments and parameters in the
“inspect library.”
https://docs.python.org/3.3/library/inspect.html#inspect.Parameter
The difference between Arguments and Parameters is
explained in the FAQs.
https://docs.python.org/3/faq/programming.html#faq-
argument-vs-parameter
209
return-statement
State
The Python glossary explains the “state” of data attributes,
or objects with value.
https://docs.python.org/3/glossary.html#term-object
Statements
The Python glossary explains “statements,” and is available
on the docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-statement
https://docs.python.org/3/reference/simple_stmts.html
timeit
Information on the timeit() function is available on the
docs.ptyhon.org website
https://docs.python.org/3/library/timeit.html
Types
210
The Python glossary explains “types,” and is available on the
docs.ptyhon.org website.
https://docs.python.org/3/glossary.html#term-type
The 3.1 topic “objects, values, and types” in the “Data Model”
reference is available on the docs.ptyhon.org website.
https://docs.python.org/3/reference/datamodel.html#index-
3
Values
The 3.1 topic “objects, values, and types” in the “Data Model”
reference is available on the docs.ptyhon.org website.
https://docs.python.org/3/reference/datamodel.html#index-
3
211
Conclusion
212
Index
?! = (Not Equal) - See Comparison Operators,
3.14, Appendix Reference
?, 4.8
…: (iPython session), 4.7
%debug, 4.3
<, 3.14, Appendix Reference
< = (Less than or Equal To), 3.14
<=, 3.14, Appendix Reference
==, 3.14, Appendix Reference
>, 3.14, Appendix Reference
>=, 3.14, Appendix Reference
Anaconda, Ch 2
Arbitrary Number of Arguments (see Function,
3.17
Arguments (see Functions), 3.17, 6.9, 7.6,
Appendix Reference
Assert, 5.5
Assign, Ch 3
Assignment statement, Ch 3
Attribute (also see value), 2.19, 3.19,
213
Appendix Reference
Behavior (see Function or Method), Appendix
Reference
Block of Code (See Suite), Ch 3
boolean, 3.6
Breakpoint, 4.5
Call Signature, 4.8, 6.9
Calling a Function, 3.17
Calls, Appendix Reference
Case sensitive , 3.2
Classes, 2.4, Appendix Reference
Code Block, 3.16
Colon, 3.2
Comment, Ch 3
Comparison Operators, 3.14
Console, Ch 2, 4.9
Container, Appendix Reference
Control Statements, 3.15
Convert Data Type, 3.6
Counter, 3.15
Data scrubbing,
Data type, 3.6
214
Debug Mode, 4.3
Define a Function, 3.17
Defined Behavior (see Methods), Appendix
Reference
Dictionary, 3.12
Dir(), 4.8
Divide and Conquer, 4.8, 4.11
DocString (also see Inspect and Signature),
3.18, 4.9
Editor, Ch 2
Elements (see Classes), Appendix Reference
Else Statement, 3.15
Endless Loop, 7.1
Except (see try and except), 5.3
float, 3.6
Focused Testing, 4.11
For Statement, 3.15, 7.20
Functions,
Function Return Values, 3.17
Global Variables, 4.8
help() function, 4.8
id() function, 3.4, 4.9
215
IDE, Ch 2
Identifier (Objects), 3.2, 3.3
If…, 3.15
Immutable, 3.4, 4.9, Appendix Reference
in (see Comparison Operators), 3.14, Appendix
Reference
Increment Counter, 3.15, 4.8
Indentation, 3.16, 4.3
Index, Ch 3
IndexError, 7.1
Infinite Loop, 7.1
Inspect, 3.18, 6.19
Instance (see Classes), Appendix Reference
Instatiation (See Classes), Appendix Reference
integer, 3.6
Integrated Desktop Environment, Ch 2
Interactive Mode, 2.10, 4.1, 4.8
Introspection, 4.8
ipdb prompt, 4.7
iPython Session, 2.10, 4.8
is (see Comparison Operators), 3.14, Appendix
Reference
216
is not (see Comparison Operators), 3.14,
Appendix Reference
Iterable, Appendix Reference
Iterate (Loop), 3.10, 3.15
Keyword Arguments, 3.17
Keywords, 3.2
len (length), 6.8
List Index Out of Range, 7.1
Lists, 3.10
Local Variables, 4.8
Logging, 4.9
Magic Functions, 4.3, 4.8, 5.1
Method (also see Functions), Appendix
Reference
Mutable, Ch 3
Namespace, 4.8
Naming Conventions, Ch 3
Nested, 3.16
None, 3.6, 3.17, 6.6
Not Equal Comparison Operator != , 3.14,
Appendix Reference
not in (see Comparison Operators), 3.14,
217
Appendix Reference
Numbers, 3.7
Objects, 3.3, Appendix Reference
Optional Arguments, 3.17
Parameters, 3.17, Appendix Reference
PEP 3131, 3.2
Plural - Naming Identifiers, 3.2
Positional Arguments, 3.17
Preferences, PEP8,
Prompt (Console), 4.7
Pseudocode, 5.1, 7.35
Python, Ch 2
Raise, 5.4
repr(), string representation (whitespace), 4.8,
7.39
Reserved Keywords, 3.2
Return values, 3.17, 6.10
Run, Ch 2
Scope, 3.4, 4.9
Script, Ch 2
Set, 3.13
Signature (see Inspect), 3.18, 6.19
218
Singular - Naming Identifiers, 3.2
Spaces, also see Whitespace, Ch 3
Special Characters, 3.2
Spyder, Ch 2
State, Appendix Reference
Statements, 3.1, 3.15
str, 3.6
String representation (see repr()), 7.39
Strings, 3.8
Style Guide for Python, see PEP8,
Suite (Block of Code), 3.16, 4.2
Syntax, 3.2
Test data, 4.12
timeit(), 4.10, 5.1
Try and Except statements, 5.3
Tuples, 3.11
Type, 3.6, 6.7, Appendix Reference
Type(), 4.8
Underscore, 3.2, 3.7
Unicode, 3.2
Value, Ch 3
Variable Explorer, 4.54
219
Variables (also see Classes), 2.14, 3.5
While Loop, 3.15, 7.6
Whitespace, 6.6, 7.39
220