Errata: June 29, 2020

Thank you for purchasing Practices of the Python Pro. Please post errata not listed below in this book's LiveBook Errata thread. We'll update this list as necessary. Thank you!

General Note, List item enumeration

Some lists, especially in liveBook, show up as numbered, while the text that follows them references letters instead. This is an artifact of the rendering and publication process. Letter A corresponds to option 1, B to option 2, and so on. This issue is not known to affect the final PDF or the print book.

Chapter 2, page 31, listing 2.2

The code as written would present users a list of options numbers 0–2, but the code later expects that the user input is in a range of 1–3. The enumerate(OPTIONS) line should read enumerate(OPTIONS, 1) to start the presented options properly at 1.

Chapter 2, page 29, section 2.2.1

The join_names() code doesn't account for the cases where there are only one or two names. To properly print a name by itself, or to print two names as Name1 and Name2, as an example, the code should read something like this:

def join_names(names):
    name_string = ''

    for index, name in enumerate(names):
        if index > 0 and len(names) > 2:
            name_string += ','
        if index > 0:
            name_string += ' '
        if index == len(names) - 1 and len(names) > 1:
            name_string += 'and '
        name_string += name
    return name_string

Chapter 3, page 48, section 3.3

The specification for the Greeter class is missing a key detail. The Greeter class should also include an __init__ method that accepts a name argument to be stored on the Greeter instance. This name should then be used in printing the greeting message.

Additionally, the first line of the expected message format should read Hi, my name is <name>, and welcome to <store>!.

Chapter 4, page 73, section 4.1.1

The timeit example prints a value to the user in milliseconds, but the return value of timeit.timeit() is in seconds. Additionally, that value is the total run time, not the average time per run. By default, timeit.timeit() runs the code 1 million times. For the right units, and to more accurately reflect the actual average, the code should read something like this:

result = timeit(setup=setup, stmt=statement, number=1_000)
print(f'Took an average of {result / 1_000}s, or {result}ms')

Chapter 6, page 120, section 6.3.3

A mistype in the AsciiDoc manuscript resulted in italicized text rather than "dunder" notation:

if name == 'main':

should read

if __name__ == '__main__':

Chapter 6, page 123, section 6.12

The text leading into the listing suggests using collections.OrderedDict, but the listing doesn't use it. The downloadable code for the chapter includes the collections.OrderedDict usage.