Python
Python
In short, this book will help you hit the ground running. Next
week, you’ll be ready to buy that Python encyclopedia.
Quick Python 3
David Matuszek
First edition published 2023
by CRC Press
6000 Broken Sound Parkway NW, Suite 300, Boca Raton, FL 33487-2742
Except as permitted under U.S. Copyright Law, no part of this book may be reprinted,
reproduced, transmitted, or utilized in any form by any electronic, mechanical, or other means,
now known or hereafter invented, including photocopying, microfilming, and recording, or in
any information storage or retrieval system, without written permission from the publishers.
For permission to photocopy or use material electronically from this work, access www.
copyright.com or contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive,
Danvers, MA 01923, 978-750-8400. For works that are not available on CCC please contact
mpkbookspermissions@tandf.co.uk
Trademark notice: Product or corporate names may be trademarks or registered trademarks
and are used only for identification and explanation without intent to infringe.
Typeset in Minion
by MPS Limited, Dehradun
To all my students,
past, present, and future
Contents
Author, xi
Preface, xiii
vii
viii ▪ Contents
Chapter 3 ■ Classes 39
3.1 Classes and Inheritance 39
3.2 Constructors and Self 41
3.3 Subclasses 44
Contents ▪ ix
Chapter 5 ■ Testing 73
5.1 Philosophy 74
5.2 Doctest 75
5.3 Unit Testing 77
5.4 Unit Test Example 80
5.5 Test Suites 81
■ Afterword 91
xi
xii ▪ Author
Jockey and All True Value, and I expect to write more. Check
them out!
david.matuszek@gmail.com
Preface
xiii
CHAPTER 1
The Absolute
Bare Minimum
While you’re there, you might want to explore the online doc-
umentation. A couple of clicks will bring you to docs.python.
org/3/, and from there the Library Reference link will bring you
to a long list of modules, each containing numerous useful
methods.
• You can spend five minutes learning how to use IDLE. This
is what I recommend if you’re in a hurry.
DOI: 10.1201/9781003356219-1 1
2 ▪ Quick Python 3
1.2 IDLE
When you run IDLE, you get a “Shell” window, into which you
can type expressions or statements at the >>> prompt.
To write complete programs, choose File > New File and enter
your code there. You have to save the file before you can run it.
The extension .py will be added automatically to the file name,
or you can add it yourself. Run your program by choosing Run >
Run Module or by hitting F5.
Spend a few minutes looking over the menus; there are things in
there that can save you time. Notice that the menus differ ac-
cording to whether you are in a shell window or a file window.
1.3 VARIABLES
Variables do not have a type, and do not have to be declared.
Variables come into existence when you assign a value to them.
Example: best_value = 36
1.6 COMPARISONS
Comparisons:
• Equals (==), not equal (!=), less than (<), less than or equal
(<=), greater than (>), and greater than or equal (>=).
• Chaining: Unlike most languages, Python lets you chain
comparisons, for example, 2 < 3 < 4 > 2. All comparisons
are performed pairwise, and the result is True if every in-
dividual comparision is True.
1.7 BOOLEANS
The two boolean (logical) values are True and False.
Python has the boolean operators not, and, and or, with the
usual meanings. The and and or operators are short-circuit; that
is, the second operand is evaluated only if necessary.
The comparison operators (<, <=, ==, !=, >=, >) also work with
booleans; True is greater than False.
In a numeric expression, True has the value 1 and False has the
value 0. In a boolean expression, all numeric zero values are
false, and all nonzero values are true. Using these facts will make
your code less explicit.
The special value None indicates “no value,” and is treated as false.
1.8 LISTS
A list is written as a sequence of values enclosed in square
brackets.
1.9 STRINGS
A string is written as a sequence of characters enclosed in quote
marks. Strings can be concatenated (added together) with the
+ operator; "Hello" + "World" gives "HelloWorld". You can
also leave out the + between literal (quoted) strings and just
separate them by spaces or tabs. (Newlines can also be used, if
the strings are enclosed in parentheses).
• \\ is a backslash character.
• \uxxxx or\uxxxxxxxx is a Unicode character (four or eight
hex digits).
1.10 COMMENTS
Comments begin with a hash mark, #, and continue to the end of
the line.
If you want to put two statements on the same line, you can
separate them with a semicolon, ;. If you are used to a language
in which every statement ends with a semicolon, this will work in
Python, it just looks strange to seasoned Python programmers.
If you are using IDLE, it will automatically indent after any line
ending with a colon. If it fails to indent, that means you forgot
the colon.
10 ▪ Quick Python 3
Rather than talk in the abstract about syntax, it’s easier to just
look at examples of each of the statement types.
x=1
• x += y is a shortcut for x = x + y
• x -= y is a shortcut for x = x - y
• …and so on, for each of the other binary operators.
For example, if x has the value 5, then the function call print
('x =', x) will print x = 5.
1.11.3 If Statements
If statements use the keywords if and (optionally) elif and
else.
if n == 1:
print("One")
elif n == 2:
print("Two")
elif n == 3:
print("Three")
else:
print("Many")
print("or maybe none at all")
You can use as many elifs as you like, each with an associated
condition, and you can have a final else. Each if, elif, or else
line ends with a colon (:). The statements under the control of
each case must be indented.
n=5
while n > 0:
print(n)
n -= 1
print("Blast off!")
The walrus operator can be used in while loops. The above code
is equivalent to
n=6
while (n := n - 1) > 0:
print(n)
print("Blast off!")
Many more functions are available but are not built in; you
have to import them from a module. (A “module” is just a file
containing code.) For example, the square root and natural
logarithm functions, sqrt and log, can be imported from the
math module.
You can omit the prompt, in which case the user will be left staring at
a blank screen and wondering why the program isn’t doing anything.
1.13 FUNCTIONS
To define a function, use the word def, the name of the function,
a parenthesized list of parameters, and a colon. Follow this with
the indented body of the function. When you have a value to
return, put the value in a return statement. For example:
(We could have put the final return statement into an else part,
but there’s no need to. It will be executed if the if-elif statement
doesn’t do anything.)
1.14 SYNTAX
There are no new concepts in what we’ve covered so far; it’s all
just syntax. Syntax is boring. How do you learn boring material?
Practice.
Pick some simple program to write, and write it. For example,
make change for any amount (in dollars, quarters, dimes, nickels,
and pennies). Determine whether an input number is prime or
composite. Find the average of numbers in a list. Whatever.
16 ▪ Quick Python 3
1.16 SUMMARY
You should now be able to understand everything about the
following program.
def is_prime(n):
"""Test if a number n is prime."""
divisor = 2
while divisor ∗ divisor <= n:
The Absolute Bare Minimum ▪ 17
if n % divisor == 0:
return False
divisor += 1
return True
def print_primes(limit):
for i in range(2, limit + 1):
if is_prime(i):
print(i, end=' ')
Of course, if you stop here, any Python programs you write will be
complicated. Python has more data types, statement types, and
functions that will make your life easier and your programs sim-
pler. This section has been titled “The Absolute Bare Minimum”
for a reason.
Keep reading!
CHAPTER 2
Better Tools
DOI: 10.1201/9781003356219-2 19
20 ▪ Quick Python 3
2.2 LISTS
A Python list is an indexable sequence of values, not necessarily
all of the same type. The first index is 0. You can create a list by
writing a comma-separated sequence of values enclosed in
brackets, [].
Examples:
You can take “slices” of a list, giving you a new list containing
some of the elements of the original list. If my_list is a list and i
and j are integers, then
You can also use slice notation on the left-hand side of an as-
signment operator. If you assign a list of values to a slice, those
values replace the values in the slice. The list of values does not
have to be the same length as the slice it replaces. For example, if
x = [0, 1, 2, 3] and you assign x[1:3] = [11, 22, 33], the
result will be that x gets the value [0, 11, 22, 33, 3].
22 ▪ Quick Python 3
Since any value can be put in a list, you can make a list of lists,
for example, grades = [["Mary", "A+"], ["Donald", "C-"]].
To get individual elements, you have to index the outer and the
inner lists separately: grades[1] is ["Donald", "C-"], so
grades[1][0] is "Donald".
x = [0] * 3
for i in range(0, 3):
x[i] = [0] * 5
2.3 TUPLES
A tuple consists of zero or more values separated by commas and
enclosed in parentheses; for example, ("John", 23). When a
tuple is by itself on the left or right side of an assignment, the
parentheses may be omitted, for example,
a, b, c = 1, 2, 3
2.4 SETS
A set is a collection of values, not necessarily all the same type. A
set literal is written as braces around a comma-separated list. For
example:
You can use a for loop to go through each element of the set in
turn, as long as you don’t care in what order the elements are
processed.
for elem in s:
print(elem)
The comparison operators (<, <=, ==, !=, >=, >) can also be used
to test subset/superset and equality/inequality relationships be-
tween two sets. set1 < set2 is True if set1 is a proper subset of
set2, that is, set1 is a subset of set2 but not equal to it.
2.5 DICTIONARIES
A dictionary (of type dict) provides a fast way of looking
something up. A dictionary literal is written as zero or more
26 ▪ Quick Python 3
Keys must be unique; you can have only one value associated
with a key. Values do not have to be unique; many keys may
have the same value.
phones["Xavier"] = 5556666
This also works for changing the value associated with the key. For
example, you could update someone’s phone number this way.
del phones["Xavier"]
Better Tools ▪ 27
The del command will give a KeyError if the key is not in the
dictionary, so check before using del. (You can use the in and
not in set operators to test if a key is in the dictionary.)
There are a lot of string methods. Many of the most useful are
listed in Appendix A. Here, we discuss only a couple of the most
useful and/or confusing string methods.
for e in my_list:
print(e)
If you need to work with not only the elements in the list, but
also their position in the list, you can use a more complicated
version of the for loop:
for e in my_set:
print(e)
for k in my_dict:
print(k) # prints just the keys
To make this more explicit, you could use the keys method of a
dictionary:
for k in my_dict.keys():
print(k) # prints just the keys
You can also just print the values by using the values method:
for v in my_dict.values():
print(v) # prints just the values
You can print both keys and values by looping over just the keys
and, for each key, looking up the value:
for k in my_dict:
print(k, "->", my_dict[k])
30 ▪ Quick Python 3
for t in my_dict.items():
print(t) # prints (key, value) tuples
for k, v in my_dict.items():
print(k, "is", v)
If you know where an error is likely to occur, you can deal with
it. For example, you might use the input function to ask the user
for an integer. Whatever the user types will be returned as a
string, which you can convert to an integer by using the int
function—unless the user types in something other than digits,
in which case you will get a ValueError.
Better Tools ▪ 31
try:
# code that could go wrong
except SomeErrorType:
# what to do if it goes wrong
finally:
# what to do afterwards
Here’s an example:
number = None
while number is None:
try:
n = input("Enter an integer: ")
number = int(n)
except Exception:
print("Try again!")
print("Your number is", number)
• If int succeeds,
• The result is put into number, the except part is
skipped, and control returns to the top of the loop,
• Since number is no longer equal to None, the loop
exits.
• If int fails,
• int raises an exception,
• Control goes to the except part, skipping over any
statements that may remain in the try part,
• "Try again!" is printed out, and control returns to
the top of the loop,
• Since number is still equal to None, the loop body is
executed again.
• When the user enters a valid integer, the loop exits and
prints out the number the user entered.
• int(5.7) # returns 5
• int("5") # returns 5
• float(5) # returns 5.0
• float("5.7") # returns 5.7
• bool("False") # returns True
• The following things are considered false: False, None,
0, 0.0, empty strings, empty lists, empty sets, empty
tuples, and empty dictionaries.
• str([1, 2, 3]) # result is '[1, 2, 3]'
2.10 SCOPE
The scope of a name is the part of the program in which the
name has meaning and can be used. Python’s scope rules are
unusual; they follow an “LEGB rule”: Local, Enclosed, Global,
Built-in. To understand this rule, it helps to remember that (1)
variables are defined by being assigned a value and (2) functions/
methods may be nested within other functions/methods.
count = 0
with open(file_name, 'r') as f:
while f.readline():
count += 1
2.12 PICKLING
Serializing (sometimes called marshalling) an object is turning it
into a linear stream of bytes. This can be done to save an object on
a file, or to transmit it to another process. The byte stream can be
deserialized (unmarshalled) to reconstruct the original object.
Pickling is not secure. A pickle file can contain code objects and data
to attack your system. Make sure that anything you unpickle comes
from a trusted source and has not been tampered with in transit.
CHAPTER 3
Classes
DOI: 10.1201/9781003356219-3 39
40 ▪ Quick Python 3
The special class object is the “root” of all classes. If you omit
superclass when you define a class, it defaults to having the
superclass object. Every class inherits from object, either di-
rectly or indirectly.
class Person(object):
name = 'Joe'
age = 23
def say_hi(self):
print('Hello, Joe.')
Classes ▪ 41
Remember that each object we create from a class has its own
copy of each of the fields (instance variables) of that class. If we
have two Person objects named joe and jane, then each of
them will have a name field and an age field.
Briefly, the name self used inside a class definition is the particular
object we are talking to.
42 ▪ Quick Python 3
Every method within a class must have self as its first parameter.
class Person(object):
def say_hi(self):
print('Hello', self.name)
def get_older(self):
self.age += 1
3.3 SUBCLASSES
A class inherits all the instance variables and methods of its
superclass. (It is a subclass of its superclass.) For example, you
might define a Friend class as a subclass of Person.
class Friend(Person):
def smile(self):
print('¯\_(^-^)_/¯')
When you create meg as an instance of Person, meg will have the
say_hi, get_older, and get_much_older methods and the
__init__ initializer, but not the smile method. When you
create bob as a Friend, bob will have all these things, and will
also have a smile method.
Classes ▪ 45
In the initializer for Friend you could copy and paste all the
work done in the initializer for Person, but it is much better
style to just call that initializer. In this case you do call __init__
directly. For example, the Friend initializer might look like this:
If you write a subclass because you want only some of the things
in its superclass, but not all of them, this is an indication that
your classes would benefit from being reorganized.
def __str__(self):
return self.name + "'s age is " + str(self.age)
Margaret's age is 19
For your own class, you can define equality and ordering by
defining some special methods in the class. (All these names use
double underscores.)
3.6 BINDINGS
In a technical sense, every value in Python is an object. However,
some objects are immutable: They cannot be changed. For ex-
ample, the number 5 is immutable; you cannot change a 5 to a 6.
If you have a variable x whose value is 5 (we say x is bound to 5),
you can use an assignment statement to change the binding of x
to 6, but 5 is still 5.
Classes ▪ 49
a = 5 # bind a to 5
b = a # copy a's binding into b
a = 6 # change the binding of a
print(b) # b is still bound to 5
Binding works the same way for mutable objects as it does for
immutable objects.
a = [1, 2, 3]
b = [1, 2, 3]
foo(a, b)
print(a, b) # [99, 2, 3] [1, 2, 3]
import copy
grades3 = copy.deepcopy(grades)
grades3[1][1] = "D+"
# grades is unchanged
CHAPTER 4
Getting Fancy
4.1 STATEMENTS
This section describes Python statements that have not been
previously covered, or that have more options than have pre-
viously been covered.
• import
• import module — makes the named module available,
after which an object or method named name in that
module may be accessed by module.name. This pre-
vents problems when the same name is imported from
more than one module.
• from module import names — imports the given names,
which do not need to be prefixed by module and a dot.
• from module import ∗ — imports all names from
module. Use with caution, as it may import names you
are not even aware of.
• import module as modname — makes the named
module available, but instead of module.name you
would use modname.name.
DOI: 10.1201/9781003356219-4 53
54 ▪ Quick Python 3
• continue
• If continue is executed within a while or for loop, any
remaining statements within the loop are skipped over,
and control returns to the top of the loop (to the test in a
while loop, or the next value in a for loop).
• continue within nested loops applies to the innermost loop.
• del variable
• Causes the variable to cease to exist (become unbound).
• else:
• Both a while loop and a for loop may be followed by an
else clause. The code in the else clause is executed
when the loop exits normally, but is not executed if the
loop terminates as the result of a break or a return.
• exec(arg)
• Executes a string, a file that has been opened, or a code
object arg. Code objects are not covered in this book.
• exec is actually a function, but it returns None as its
value, so it is often used as if it were a statement.
• exec is not secure, so do not use it if there is any chance
that the arg contains malicious or harmful code.
• nonlocal variables
• Functions may be nested inside other functions. By
default, an inner function can access but not change the
variables of an enclosing function. If the inner function
declares variables to be nonlocal, it can both access
them and change them.
• The rules are very similar to those of local and global
variables.
56 ▪ Quick Python 3
• pass
• The pass statement does nothing. It is occasionally
useful when the syntax requires the presence of a
statement, but there is nothing in particular to be done.
• An ellipsis (three dots, ...) is the same as pass.
• print(expr1, ... , exprN, sep=sepString, end=endString,
file=outputFile)
• Evaluates and prints the expressions, with sepString between
them, and endString after the last expression, on outputFile.
The keyword arguments sep, end, and file may be
omitted, with the default values ' ' (a single space), '\n'
(a newline), and stdout, respectively.
• raise
• raise Exception raises the named Exception, which
might be handled later by a try-except statement.
Python provides a large number of exception types, or
you can define your own by subclassing Exception.
• raise Exception(expression) raises the named Exception,
and uses the result of the expression as a message in the
exception.
• raise by itself in an except clause re-raises the same
exception.
4.2 IDENTIFIERS
Identifiers begin with a letter or underscore and may contain
letters, underscores, and digits; case is significant. Unicode
characters may be used.
Beginning with Python 3.5, you can enter type hints to specify
what type of value a variable is expected to hold. These hints are
treated as comments; they have absolutely no effect on the run-
ning program. Some IDEs can use type hints to do some static
code checking, and this may become more prevalent in the future.
With this import, you can use type hints such as List[int], Set
[int], Dict[str, str], Union[int, float], and Optional[str],
as well as more complex type hints such as List[Set[int]]. The
Union type hint specifies that the value may be any of the listed types,
while the Optional type hint specifies that the value is either the
given type or None.
A type hint may be assigned a name, after which the name can be
used as a type hint. This can be very helpful for documenting
complex data structures.
4.4 NUMBERS
A decimal integer consists of either the number 0, or a sequence
of digits not beginning with 0.
4.5 STRINGS
A string is written as a sequence of zero or more characters
enclosed in single quotes ('...'), double quotes ("..."), triple
single quotes ('''...'''), or triple double quotes ("""...""").
It can be treated as a list of characters.
4.6 F-STRINGS
There are three ways of formatting a string: Using f-strings,
using the format method, and using the old-style % formatting.
Generally the f-string method is recommended.
• print(f'Area is {5∗7/2}.')
• Prints: Area is 17.5.
• print(f'Area is {5∗7/2=}.')
• Prints: Area is 5∗7/2=17.5.
• print(f'Area is {5∗7/2:9.3f}.')
• Prints: Area is 17.500.
Getting Fancy ▪ 61
The syntax of the formatting codes is quite complex, and will not
be covered here. Instead, we will just give a few simple examples.
print('pi is {:8.4f}'.format(pi))
This code will print the string 'pi is 3.1416', with three
spaces between the word is and the 3.
• ~ bitwise complement
• & bitwise and
62 ▪ Quick Python 3
• | bitwise or
• ^ bitwise exclusive or
• << left shift (right operand is the amount to shift the left
operand)
• >> right shift (right operand is the amount to shift the left
operand)
4.9 ITERATORS
An iterable object is any object that can be stepped through.
Iterable objects include lists, sets, tuples, strings, dictionaries,
ranges, and files. An iterator is an object that keeps track of
where it is in stepping through an iterable object, and provides
the next value as needed.
class MyList():
def __init__(self, ls):
self.ls = ls
def __iter__(self):
return Reverser(self.ls)
class Reverser():
def __init__(self, ls):
self.ls = ls
self.index = len(self.ls)
def __next__(self):
self.index = self.index - 1
Getting Fancy ▪ 65
if self.index >= 0:
return self.ls[self.index]
raise StopIteration
If the classes are combined so that the iterable is its own iterator,
then only one iterator at a time can be supported.
A for loop may use any iterable object. In for loops, the
StopIteration exception does not result in an error; it merely
terminates the for loop. For example,
ls = MyList([1, 2, 3, 4])
for e in ls:
print(e)
Alternatively, you can use the iter and next methods directly,
and handle the StopIteration exception yourself. This is es-
sentially what the previous for loop is doing.
ls = MyList([1, 2, 3, 4])
it = iter(ls)
while True:
try:
print(next(it))
except StopIteration:
break
4.10 GENERATORS
A generator is a kind of iterator. It generates values one at a
time, as needed, but it isn’t necessarily tied to a particular kind of
object.
word = 'generator'
gen = (c for c in word if c in 'aeiou')
for i in gen:
print(i, end=' ')
You can write functions that act as generators, by using yield in-
stead of return. Here is an example generator for powers of 2:
def powers_of_two():
n=2
for i in range(0, 5):
yield n
n ∗= 2
Getting Fancy ▪ 67
gen = powers_of_two()
for n in gen:
print(n)
gen = powers_of_two()
while True:
try:
print(next(gen))
except StopIteration:
break
• An expression.
• name=value, to give a value to the parameter with that name.
This is called a named argument or keyword argument.
Getting Fancy ▪ 69
In this book we consider only the first point above: that functions
are objects. We will consider only a single example of such a use.
def biggest(values):
big = values[0]
for v in values:
if v > big:
big = v
return big
Since > can also be used to compare strings, this function can be
used to find the lexicographically largest string in a list of strings.
But for almost any other purpose (finding the smallest number,
the longest string, etc.) you have to write another, almost iden-
tical function.
Instead of writing more and more functions, we can replace the >
with a generic test:
Getting Fancy ▪ 71
or like this:
Testing
DOI: 10.1201/9781003356219-5 73
74 ▪ Quick Python 3
5.1 PHILOSOPHY
Use of a proper test framework has a large number of advantages:
5.2 DOCTEST
A lot of testing is done on an ad hoc basis—the programmer
types in function calls at the Python prompt (>>>), and looks to
see if the result is correct. Doctest provides a very low-effort
way to preserve these tests.
To use doctest, simply copy the ad hoc tests done at the prompt,
including the >>> prompt, and paste them into the doc comment
for the function being tested. The following get_digits function
returns a list of all the digits in an integer or a string:
def get_digits(number):
"""Return a list of digits in an int or string."""
string = str(number)
return [x for x in string if x.isdigit()]
>>> get_digits("124c41")
['1', '2', '4', '4', '1']
>>> get_digits(1213141)
['1', '2', '1', '3', '1', '4', '1']
To use doctest, the ad hoc tests done at the Python prompt are
copied and pasted into the docstring.
76 ▪ Quick Python 3
def get_digits(number):
"""Return a list of digits in an int or string."""
>>> get_digits("124c41")
['1', '2', '4', '4', '1']
>>> get_digits(1213141)
['1', '2', '1', '3', '1', '4', '1']
"""
string = str(number)
return [x for x in string if x.isdigit()]
import doctest
doctest.testmod()
The testmod method will locate all the ad hoc tests in the
comments and run them again. It will print information about
all failed tests; if all tests pass, testmod doesn’t print anything
(though it does return a summary result).
Notes:
• import unittest
• import fileToBeTested or
from fileToBeTested import *
• Reminder: If you use from file import * then you
don’t have to precede every function call with the name
of the file it was imported from.
• Write a class SomeName(unittest.TestCase). Within
the class,
• Define methods setUp(self) and tearDown(self), if
wanted. These are both optional.
• Provide one or more testSomething(self) methods.
You may include other methods, but the names of test
methods must begin with test.
• At the end of the test file, put unittest.main().
way you can make sure that the results of running one test do
not affect the results of a later test.
Each test method should typically test only one function, though it
may call that function many times. If a function behaves differ-
ently for different kinds of input (for example, positive or negative
numbers), it’s a good idea to write multiple test methods.
def test_add(self):
self.assertEqual(4, add(2, 2))
self.assertEqual(0, add(2, -2))
If any assertion in a test method fails, the test fails and the re-
maining assertions in that method are not tested. For this reason,
test methods should not become too long.
• self.assertEqual(expected, actual)
• self.assertAlmostEqual(expected, actual) for floating
point numbers.
• self.assertTrue(boolean) and self.assertFalse
(boolean).
Testing ▪ 79
self.assertRaises(ZeroDivisionError, 5/0)
then the argument 5/0 would be evaluated and would raise the
exception before assertRaises can be called.
if __name__ == '__main__':
main()
and put the following code at the end of the test file:
unittest.main()
In this way, the program will be run if loaded from the program
file, and the tests will be run if loaded from the test file.
80 ▪ Quick Python 3
def get_digits(number):
"""Return a list of digits in an int or string."""
string = str(number)
return [x for x in string if x.isdigit()]
def main():
s = input("Enter something: ")
digits = get_digits(s)
print("Digits found:", digits)
if digits != []:
main()
In file get_digits_test.py:
import unittest
from get_digits import *
class test_get_digits(unittest.TestCase):
def test_get_digits(self):
s = get_digits("<0.12-34 56abc789x")
self.assertEqual(list("0123456789"),
get_digits(s))
self.assertEqual(list("1230"),
get_digits(1230))
unittest.main()
Testing ▪ 81
import unittest
import testfoo, testbar
def suite():
suite = unittest.TestSuite()
suite.addTest(
unittest.makeSuite(
testfoo.TestFoo))
suite.addTest(
unittest.makeSuite(
testbar.TestBar))
return suite
if __name__ == '__main__':
test_suite = suite()
runner = unittest.TextTestRunner()
runner.run (test_suite)
CHAPTER 6
Graphical User
Interfaces
6.1 DIALOGS
There are several GUI (Graphical User Interface, pronounced
“gooey”) systems that can be used with Python. This chapter
discusses Tkinter, which comes bundled with the standard
Python distribution.
• messagebox.showinfo(title, message)
• messagebox.showwarning(title, message)
• messagebox.showerror(title, message)
• All the above are essentially the same; the difference is
which icon is displayed. All provide for a title, a message,
and an OK button.
DOI: 10.1201/9781003356219-6 83
84 ▪ Quick Python 3
6.2 TKINTER
GUI programs work differently than programs without a GUI.
Instead of all code under control of a main method, the program
creates a GUI, and thereafter everything that happens is a result
of some user interaction with the GUI. For example, the user
clicks a button, and that causes certain code to be executed.
Start with
top = Tk()
top.mainloop()
import tkinter
root = tkinter.Tk()
root.withdraw()
• row=n The row to put the widget in. Default is the first
available row.
• column=n The column to put the widget in; default is 0.
• rowspan=n The number of rows the widget should occupy.
• columnspan=n The number of columns the widget should
occupy.
• ipadx=n, ipady=n The amount (in pixels) to pad the
widget, horizontally and vertically.
• sticky=d Where to put the widget if in a larger space. d is
one of N, S, E, W, NE, SE, NW, SW.
def roll():
n = str(randint(1, 6))
result.configure(text=n)
top = Tk()
roll_button.grid(row=0)
result.grid(row=1)
Afterword
If you have made it this far in this book, and have tried out
things as you went, you should have a solid foundation for
learning more, and going wherever your interests and require-
ments take you.
Happy programming!
DOI: 10.1201/9781003356219-7 91
Appendix A:
String Methods
93
94 ▪ Appendix A: String Methods
97
98 ▪ Appendix B: Numerical Functions
The math module includes a lot of methods that are not available
by default. Here are some of them.
Here are some of the functions that you get if you import the
random module:
For example,
101
102 ▪ Appendix C: Statistics
prints:
prints:
28.26, 798.67
H ERE ARE SOME FUNCTIONS that take iterable objects (lists, sets,
tuples, strings, dictionaries, ranges, files, and possibly others).
103
104 ▪ Appendix D: Functions on Iterables
105
106 ▪ Appendix E: Operating System Commands
• assertEqual(a, b)
• assertNotEqual(a, b)
• assertAlmostEqual(a, b) # for floating point numbers
• assertAlmostEqual(a, b, places)
• assertTrue(x)
• assertFalse(x)
• assertIs(a, b) # tests for identity
• assertIsNot(a, b)
• assertIsNone(x)
• assertIsNotNone(x)
• assertIn(a, b)
107
108 ▪ Appendix F: Unit Test Methods
• assertNotIn(a, b)
• assertIsInstance(a, b)
• assertNotInstance(a, b)
• assertRaises(exception, function, arguments)
These methods are not called directly. Instead, they should be put
in one or more methods whose names begin with self.. Executing
unittest.main() will find and execute all such methods.
Index
109
110 ▪ Index