Fundamentals of Python: Data Structures 2nd Edition Kenneth A. Lambert - Ebook PDF Instant Download
Fundamentals of Python: Data Structures 2nd Edition Kenneth A. Lambert - Ebook PDF Instant Download
https://ebooksecure.com/download/fundamentals-of-python-data-
structures-ebook-pdf/
https://ebooksecure.com/download/fundamentals-of-python-first-
programs-2nd-edition-ebook-pdf/
https://ebooksecure.com/download/data-structures-algorithms-in-
python-ebook-pdf-2/
https://ebooksecure.com/download/data-structures-algorithms-in-
python-ebook-pdf/
http://ebooksecure.com/product/ebook-pdf-fundamentals-of-python-
first-programs-2nd-edition/
Data Structures - eBook PDF
https://ebooksecure.com/download/data-structures-ebook-pdf/
http://ebooksecure.com/product/ebook-pdf-principles-of-music-2nd-
edition-by-philip-lambert/
http://ebooksecure.com/product/ebook-pdf-introduction-to-machine-
learning-with-python-a-guide-for-data-scientists/
https://ebooksecure.com/download/data-structures-and-
applications-a-simple-and-systematic-approach-ebook-pdf/
http://ebooksecure.com/product/ebook-pdf-starting-out-with-java-
from-control-structures-through-data-structures-3rd-edition/
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
second Edition
Fundamentals of Python:
Data STRUCTURES
Kenneth A. Lambert
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
This is an electronic version of the print textbook. Due to electronic rights restrictions,
some third party content may be suppressed. Editorial review has deemed that any suppressed
content does not materially affect the overall learning experience. The publisher reserves the right
to remove content from this title at any time if subsequent rights restrictions require it. For
valuable information on pricing, previous editions, changes to current editions, and alternate
formats, please visit www.cengage.com/highered to search by ISBN#, author, title, or keyword for
materials in your areas of interest.
Important Notice: Media content referenced within the product description or the product
text may not be available in the eBook version.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Fundamentals of Python: © 2019, 2014 Cengage Learning, Inc.
Data Structures, Second Edition
Unless otherwise noted, all content is © Cengage.
Kenneth A. Lambert
ALL RIGHTS RESERVED. No part of this work covered by the
copyright herein may be reproduced or distributed in any form or
SVP, GM Skills & Global Product by any means, except as permitted by U.S. copyright law, without
Management: Jonathan Lau the prior written permission of the copyright owner.
Product Manager: Chris Shortt For product information and technology assistance, c ontact us
at Cengage Customer & Sales Support,
Product Assistant: Thomas Benedetto
1-800-354-9706 or support.cengage.com.
Executive Director, Content Design: Marah
Bellegarde
For permission to use material from this text or product,
Director, Learning Design: Leigh Hefferon submit all requests online at
www.cengage.com/permissions.
Learning Designer: Kate Mason
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Table of Contents
iii
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
contents
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
contents
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
contents
Glo s s ar y �����������������������������������������������������401
Welcome to Fundamentals of Python: Data Structures, 2nd Edition. This text is intended
for a second semester course in programming and problem solving with data structures. It
covers the material taught in a typical Computer Science 2 course (CS2) at the undergradu-
ate level. Although this book uses the Python programming language, you need only have a
basic knowledge of programming in a high-level programming language before beginning
Chapter 1.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
P r e fa c e Why Python?
Why Python?
Computer technology and applications have become increasingly more sophisticated over
the past three decades, and so has the computer science curriculum, especially at the intro-
ductory level. Today’s students learn a bit of programming and problem solving and are
then expected to move quickly into topics like software development, complexity analysis,
xii
and data structures that, 30 years ago, were relegated to advanced courses. In addition,
the ascent of object-oriented programming as the dominant paradigm has led instructors
and textbook authors to bring powerful, industrial-strength programming languages such
as C++ and Java into the introductory curriculum. As a result, instead of experiencing the
rewards and excitement of solving problems with computers, beginning computer science
students often become overwhelmed by the combined tasks of mastering advanced con-
cepts as well as the syntax of a programming language.
This book uses the Python programming language as a way of making the second course
in computer science more manageable and attractive for students and instructors alike.
Python has the following pedagogical benefits:
•• Python has simple, conventional syntax. Python statements are very close to those of
pseudocode algorithms, and Python expressions use the conventional notation found
in algebra. Thus, you can spend less time dealing with the syntax of a programming
language and more time learning to solve interesting problems.
•• Python has safe semantics. Any expression or statement whose meaning violates the
definition of the language produces an error message.
•• Python scales well. It is easy for beginners to write simple programs in Python. Python
also includes all the advanced features of a modern programming language, such as
support for data structures and object-oriented software development, for use when
they become necessary, especially in the second course in computer science
•• Python is highly interactive. You can enter expressions and statements at an interpreter’s
prompts to try out experimental code and receive immediate feedback. You can also
compose longer code segments and save them in script files to be loaded and run as
modules or stand-alone applications.
•• Python is general purpose. In today’s context, this means that the language includes
resources for contemporary applications, including media computing and web
services.
•• Python is free and is in widespread use in the industry. You can download Python to run
on a variety of devices. There is a large Python user community, and expertise in Python
programming has great resume value.
To summarize these benefits, Python is a comfortable and flexible vehicle for expressing
ideas about computation, both for beginners and for experts. If you learn these ideas well
in the first year, you should have no problems making a quick transition to other lan-
guages needed for courses later in the curriculum. Most importantly, you will spend less
time staring at a computer screen and more time thinking about interesting problems
to solve.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Organization of this Book P r e fa c e
collection is illustrated with one or more applications, and then several implementations
are developed, and their performance trade-offs are analyzed.
Chapters 10 through 12 present advanced data structures and algorithms as a transition to
later courses in computer science. Chapter 10 discusses various tree structures, including
binary search trees, heaps, and expression trees. Chapter 11 examines the implementation
xiv of the unordered collections, bags, sets, and dictionaries, using hashing strategies.
Chapter 12 introduces graphs and graph-processing algorithms.
As mentioned earlier, this book is unique in presenting a professional-quality framework of
collection types. Instead of encountering a series of apparently unrelated collections, you
will explore the place of each collection in an integrated whole. This approach allows you
to see what the collection types have in common as well as what makes each one unique.
At the same time, you will be exposed to a realistic use of inheritance and class hierarchies,
topics in object-oriented software design that are difficult to motivate and exemplify at this
level of the curriculum.
Special Features
This book explains and develops concepts carefully, using frequent examples and diagrams.
New concepts are then applied in complete programs to show how they aid in solving prob-
lems. The chapters place an early and consistent emphasis on good writing habits and neat,
readable documentation.
The book includes several other important features:
•• Case studies—These present complete Python programs ranging from the simple to the
substantial. To emphasize the importance and usefulness of the software development life
cycle, case studies are discussed in the framework of a user request, followed by analysis,
design, implementation, and suggestions for testing, with well-defined tasks performed at
each stage. Some case studies are extended in end-of-chapter programming projects.
•• Chapter summaries—Each chapter after the first one ends with a summary of the
major concepts covered in the chapter.
•• Key terms—When a new term is introduced in the text, it appears in bold face.
Definitions of the key terms are also collected in a glossary.
•• Exercises—Most major sections of each chapter after the first one end with exercise
questions that reinforce the reading by asking basic questions about the material in the
section. After Chapter 2, each chapter ends with review questions.
•• Programming projects—Each chapter ends with a set of programming projects of
varying difficulty.
objectives have been added to the beginning of each chapter. Several new figures have been
added to illustrate concepts, and many programming projects have been added or reworked.
A new section on iterators and higher-order functions has been added to Chapter 2. Finally,
a new section on Lisp-like lists, recursive list processing, and functional programming has
been added to Chapter 9.
xv
Instructor Resources
MindTap
MindTap activities for Fundamentals of Python: Data Structures are designed to help stu-
dents master the skills they need in today's workforce. Research shows employers need
critical thinkers, troubleshooters, and creative problem-solvers to stay relevant in our
fast-paced, technology-driven world. MindTap helps you achieve this with assignments
and activities that provide hands-on practice and real-life relevance. Students are guided
through assignments that help them master basic knowledge and understanding before
moving on to more challenging problems.
All MindTap activities and assignments are tied to defined unit learning objectives. H
ands-on
coding labs provide real-life application and practice. Readings and dynamic visualizations
support the lecture, while a post-course assessment measures exactly how much a class
stands in terms of progress, engagement, and completion rates. Use the content and learning
path as-is, or pick and choose how our materials will wrap around yours. You control what
the students see and when they see it. Learn more at http://www.cengage.com/mindtap/.
xvi
The first-of-its-kind digital subscription designed specially to lower costs. Students get total
access to everything Cengage has to offer on demand—in one place. That’s 20,000 eBooks,
2,300 digital learning products, and dozens of study tools across 70 disciplines and over
675 courses. Currently available in select markets. Details at www.cengage.com/unlimited
Acknowledgments
I would like to thank my friend, Martin Osborne, for many years of advice, friendly
criticism, and encouragement on several of my book projects.
I would also like to thank my students in Computer Science 112 at Washington and Lee
University for classroom testing this book over several semesters.
Finally, I would like to thank Kristin McNary, Product Team Manager; Chris Shortt, Product
Manager; Maria Garguilo and Kate Mason, Learning Designers; Magesh Rajagopalan, Senior
Project Manager; Danielle Shaw, Tech Editor; and especially Michelle Ruelos Cannistraci,
Senior Content Manager, for handling all the details of producing this edition of the book.
Dedication
To Brenda Wilson, with love and admiration.
Kenneth A.Lambert
Lexington, VA
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1
Basic Python
Programming
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
This chapter gives a quick overview of Python programming. It is intended to bring those
new to or rusty in Python up to speed, but it does not pretend to be a thorough introduc-
tion to computer science or the Python programming language. For a more detailed treat-
ment of programming in Python, see my book Fundamentals of Python: First Programs,
Second Edition (Cengage Learning, 2019). For documentation on the Python programming
2
language, visit www.python.org.
If your computer already has Python, check the version number by running the python
or python3 command at a terminal prompt. (Linux and Mac users first open a terminal
window, and Windows users first open a DOS window.) You are best off using the most
current version of Python available. Check for that at www.python.org, and download and
install the latest version if necessary. You will need Python 3.0 or higher to run the pro-
grams presented in this book.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Basic Program Elements
import random
def main():
"""Inputs the bounds of the range of numbers
and lets the user guess the computer’s number until
the guess is correct."""
smaller = int(input("Enter the smaller number: ")) 3
larger = int(input("Enter the larger number: "))
myNumber = random.randint(smaller, larger)
count = 0
while True:
count += 1
userNumber = int(input("Enter your guess: "))
if userNumber < myNumber:
print("Too small")
elif userNumber > myNumber:
print("Too large")
else:
print("You’ve got it in", count, "tries!")
break
if __name__ == "__main__":
main()
Note that the code and its trace appear in the colors black, blue, orange, and green. Python’s
IDLE uses color coding to help the reader recognize various types of program elements.
The role of each color will be explained shortly.
To create or edit a Python module, try using Python’s IDLE (short for Integrated
DeveLopment Environment). To start IDLE, enter the idle or idle3 command at a terminal
prompt or launch its icon if it is available. You can also launch IDLE by double-clicking on
a Python source code file (any file with a .py extension) or by right-clicking on the file and
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
selecting Open or Edit with IDLE. Make sure that your system is set to open IDLE when
files of this type are launched (this is the default on macOS but not on Windows).
IDLE gives you a shell window for interactively running Python expressions and statements.
Using IDLE, you can move back and forth between editor windows and the shell window to
develop and run complete programs. IDLE also formats your code and color-codes it.
4
When you open an existing Python file with IDLE, the file appears in an editor window, and
the shell pops up in a separate window. To run a program, move the cursor into the editor
window and press the F5 (function-5) key. Python compiles the code in the editor window
and runs it in the shell window.
If a Python program appears to hang or not quit normally, you can exit by pressing Ctrl+C
or closing the shell window.
Program Comments
A program comment is text ignored by the Python compiler but valuable to the reader as
documentation. An end-of-line comment in Python begins with a # symbol and extends to
the end of the current line. It is color-coded in red. For example:
# This is an end-of-line comment.
A multiline comment is a string enclosed in triple single quotes or triple double quotes.
Such comments, which are colored green, are also called docstrings, to indicate that they
can document major constructs within a program. The numberguess program shown
earlier includes two doc strings. The first one, at the top of the program file, serves as a
comment for the entire numberguess module. The second one, just below the header of the
main function, describes what this function does. As we shall see shortly, docstrings play a
critical role in giving help to a programmer within the Python shell.
Lexical Elements
The lexical elements in a language are the types of words or symbols used to construct
sentences. As in all high-level programming languages, some of Python’s basic symbols are
keywords, such as if, while, and def, which are colored orange. Also included among lexical
items are identifiers (names), literals (numbers, strings, and other built-in data structures),
operators, and delimiters (quotation marks, commas, parentheses, square brackets, and
braces). Among the identifiers are the names of built-in functions, which are colored purple.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Basic Program Elements
All Python names, other than those of built-in functions, are color-coded in black, except
when they are introduced as function, class, or method names, in which case they appear
in blue. A name can begin with a letter or an underscore (_), followed by any number of
letters, underscores, or digits.
In this book, the names of modules, variables, functions, and methods are spelled in lower-
case letters. With the exception of modules, when one of these names contains one or more 5
embedded words, the embedded words are capitalized. The names of classes follow the
same conventions but begin with a capital letter. When a variable names a constant, all the
letters are uppercase, and an underscore separates any embedded words. Table 1-1 shows
examples of these naming conventions.
Use names that describe their role in a program. In general, variable names should
be nouns or adjectives (if they denote Boolean values), whereas function and method
names should be verbs if they denote actions, or nouns or adjectives if they denote values
returned.
Syntactic Elements
The syntactic elements in a language are the types of sentences (expressions, statements,
definitions, and other constructs) composed from the lexical elements. Unlike most high-
level languages, Python uses white space (spaces, tabs, or line breaks) to mark the syntax
of many types of sentences. This means that indentation and line breaks are significant in
Python code. A smart editor like Python’s IDLE can help indent code correctly. The pro-
grammer need not worry about separating sentences with semicolons and marking blocks
of sentences with braces. In this book, I use an indentation width of four spaces in all
Python code.
Literals
Numbers (integers or floating-point numbers) are written as they are in other program-
ming languages. The Boolean values True and False are keywords. Some data structures,
such as strings, tuples, lists, and dictionaries, also have literals, as you will see shortly.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
String Literals
You can enclose strings in single quotes, double quotes, or sets of three double quotes or
three single quotes. The last notation is useful for a string containing multiple lines of text.
Character values are single-character strings. The \ character is used to escape nongraphic
characters such as the newline (\n) and the tab (\t), or the \ character itself. The next code
6 segment, followed by the output, illustrates the possibilities.
print("Using double quotes")
print('Using single quotes')
print("Mentioning the word ‘Python’ by quoting it")
print("Embedding a\nline break with \\n")
print("""Embedding a
line break with triple quotes""")
Output:
Using double quotes
Using single quotes
Mentioning the word 'Python' by quoting it
Embedding a
line break with \n
Embedding a
line break with triple quotes
The operators have the standard precedence (selector, function call, subscript, arithmetic,
comparison, logical, assignment). Parentheses are used in the usual manner, to group sub-
expressions for earlier evaluation.
The ** and = operators are right associative, whereas the others are left associative.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Basic Program Elements
Function Calls
Functions are called in the usual manner, with the function’s name followed by a parenthe-
sized list of arguments. For example:
min(5, 2) # Returns 2
Python includes a few standard functions, such as abs and round. Many other functions are 7
available by import from modules, as you will see shortly.
Like most other languages, Python allows operands of different numeric types in arithmetic
expressions. In those cases, the result type is the same type as the most general operand
type. For example, the addition of an int and a float produces a float as the result.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
its arguments are displayed. To prevent this from happening, you can give the optional
argument end a value of the empty string, as follows:
print("The cursor will stay on this line, at the end", end = "")
Required arguments have no default values. Optional arguments have default values and
can appear in any order when their keywords are used, as long as they come after the
8
required arguments.
For example, the standard function round expects one required argument, a rounded num-
ber, and a second, optional argument, the number of figures of precision. When the second
argument is omitted, the function returns the nearest whole number (an int). When the
second argument is included, the function returns a float. Here are some examples:
>>> round(3.15)
3
>>> round(3.15, 1)
3.2
In general, the number of arguments passed to a function when it is called must be at least
the same number as its required arguments.
Standard functions and Python’s library functions check the types of their arguments when
the function is called. Programmer-defined functions can receive arguments of any type,
including functions and types themselves.
sets PI to the value 3.1416. The syntax of a simple assignment statement is:
<identifier> = <expression>
Assignment statements must appear on a single line of code, unless the line is broken after
a comma, parenthesis, curly brace, or square bracket. When these options are unavailable,
another means of breaking a line within a statement is to end it with the escape symbol \.
You typically place this symbol before or after an operator in an expression. Here are some
admittedly unrealistic examples:
minValue = min(100,
200)
product = max(100, 200) \
* 30
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Basic Program Elements
When you press Enter after a comma or the escape symbol, IDLE automatically indents the
next line of code.
import Statements
The import statement makes visible to a program the identifiers from another module.
These identifiers might name objects, functions, or classes. There are several ways to
express an import statement. The simplest is to import the module name, as in:
import math
This makes any name defined in the math module available to the current module, by using
the syntax math.<name>. Thus, math.sqrt(2) would return the square root of 2.
A second style of importing brings in a name itself, which you can use directly without the
module name as a prefix:
from math import sqrt
print(sqrt(2))
You can import all names from a module using the * operator, but that is not usually
considered good programming practice.
Note that if a module is not the built-in module that Python loads when the shell starts, the
programmer must first import that module before asking for help on it. For example, the
following session with the shell displays the documentation for the numberguess program
discussed earlier in this chapter:
>>> import numberguess
10 >>> help(numberguess)
Help on module numberguess:
NAME
numberguess
DESCRIPTION
Author: Ken Lambert
Plays a game of guess the number with the user.
FUNCTIONS
main()
Inputs the bounds of the range of numbers,
and lets the user guess the computer’s number until
the guess is correct.
FILE
/Users/ken/Documents/CS2Python/Chapters/Chapter1/numberguess.py
Control Statements
Python includes the usual array of control statements for sequencing, conditional execu-
tion, and iteration. A sequence of statements is a set of statements written one after the
other. Each statement in a sequence must begin in the same column. This section examines
the control statements for conditional execution and iteration.
Conditional Statements
The structure of Python’s conditional statements is similar to that of other languages. The
keywords if, elif, and else are significant, as is the colon character and indentation.
The syntax of the one-way if statement is:
if <Boolean expression>:
<sequence of statements>
A Boolean expression is any Python value; as mentioned earlier, some of these count as
False, and the others count as True. If the Boolean expression is True, the sequence of
statements is run; otherwise, nothing happens. The sequence of (one or more) statements
must be indented and aligned at least one space or tab (typically four spaces). The colon
character is the only separator; if there is only one statement in the sequence, it may imme-
diately follow the colon on the same line.
The syntax of the two-way if statement is:
if <Boolean expression>:
<sequence of statements>
else:
<sequence of statements>
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Control Statements
Note the indentation and the colon following the keyword else. Exactly one of these two
sequences of statements will be run. The first sequence is run if the Boolean expression is
True; the second sequence is run if the Boolean expression is False.
The purpose of this if statement is to allow the programmer either to run the module as a
standalone program or to import it from the shell or another module. Here is how this works:
every Python module includes a set of built-in module variables, to which the Python vir-
tual machine automatically assigns values when the module is loaded. If the module is being
loaded as a standalone program (either by running it from a terminal prompt or by loading it
from an IDLE window), the module’s __name__ variable is set to the string "__main__".
Otherwise, this variable is set to the module’s name—in this case, "numberguess". Either
assignment is accomplished before any of the code within the module is loaded. Thus, when
control reaches the if statement at the end of the module, the module’s main function will be
called only if the module has been launched as a standalone program.
The if __name__ == "__main__" idiom is useful when developing standalone program
modules, because it allows the programmer to view help on the module just by importing it
into the shell. Likewise, the programmer can use this idiom in supporting modules to run a
test bed function during module development within IDLE.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
Loop Statements
The structure of Python’s while loop statement is similar to that of other languages. Here is
the syntax:
while <Boolean expression>:
<sequence of statements>
12
The next example computes and prints the product of the numbers from 1 to 10:
product = 1
value = 1
while value <= 10:
product *= value
value += 1
print(product)
Note the use of the extended assignment operator *=. The line of code in which this
appears is equivalent to:
product = product * value
Python includes a for loop statement for more concise iteration over a sequence of values.
The syntax of this statement is:
for <variable> in <iterable object>:
<sequence of statements>
When this loop runs, it assigns to the loop variable each value contained in the iterable object
and runs the sequence of statements in the context of each such assignment. Examples of
iterable objects are strings and lists. The next code segment uses Python’s range function,
which returns an iterable sequence of integers, to compute the product shown earlier:
product = 1
for value in range(1, 11):
product *= value
print(product)
Python programmers generally prefer a for loop to iterate over definite ranges or sequences
of values. They use a while loop when the continuation condition is an arbitrary Boolean
expression.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Strings and Their Operations
Operators
When strings are compared with the comparison operators, the pairs of characters at each
position in the two strings are compared, using ASCII ordering. Thus, 'a' is less than 'b',
but 'A' is less than 'a'. Note that in this book, we enclose single-character strings in single
quotes and multi-character strings in double quotes.
13
The + operator builds and returns a new string that contains the characters of the two
operands.
The subscript operator in its simplest form expects an integer in the range from 0 to the
length of the string minus 1. The operator returns the character at that position in the
string. Thus:
"greater"[0] # Returns 'g'
Although a string index cannot exceed its length minus 1, negative indexes are allowed.
When an index is negative, Python adds this value to the string’s length to locate the char-
acter to be returned. In these cases, the index provided cannot be less than the negation of
the string’s length.
Strings are immutable; that is, once you create them, you cannot modify their internal
contents. Thus, you cannot use a subscript to replace the character at a given position in a
string.
A variation of the subscript, called the slice operator, is what you use to obtain a substring
of a string. The syntax of the slice is:
<a string>[<lower>:<upper>]
The value of <lower>, if it is present, is an integer ranging from 0 to the length of the string
minus 1. The value of <upper>, if it is present, is an integer ranging from 0 to the length of
the string.
When you omit both values, the slice returns the entire string. When the first value is
omitted, the slice returns a substring starting with the string’s first character. When the
second value is omitted, the slice returns a substring ending with the string’s last character.
Otherwise, the slice returns a substring starting with the character at the lower index and
ending with the character at the upper index minus 1.
Here are some examples of the slice operator in action:
"greater"[:] # Returns "greater"
"greater"[2:] # Returns "eater"
"greater"[:2] # Returns "gr"
"greater"[2:5] # Returns "eat"
The reader is encouraged to experiment with the slice operator in the Python shell.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
Note that when the exponent reaches 10, the output of the second column shifts over by a
space and looks ragged. The output would look neater if the left column were left-justified
and the right column were right-justified. When you format floating-point numbers for
output, you should specify the number of digits of precision to be displayed as well as the
field width. This is especially important when displaying financial data in which exactly two
digits of precision are required.
Python includes a general formatting mechanism that allows the programmer to specify
field widths for different types of data. The next session shows how to right justify and left
justify the string "four" within a field width of 6:
>>> "%6s" % "four" # Right justify
' four'
>>> "%-6s" % "four" # Left justify
'four '
The first line of code right justifies the string by padding it with two spaces to its left. The
next line of code left justifies by placing two spaces to the string’s right.
The simplest form of this operation is the following:
<format string> % <datum>
This version contains a format string, the format operator %, and a single data value to
be formatted. The format string can contain string data and other information about
the format of the datum. To format the string data value, you can use the notation
%<field width>s in the format string. When the field width is positive, the datum is
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Strings and Their Operations
right-justified; when the field width is negative, you get left justification. If the field width is
less than or equal to the datum’s print length in characters, no justification is added. The
% operator works with this information to build and return a formatted string.
To format integers, the letter d is used instead of s. To format a sequence of data values,
you construct a format string that includes a format code for each datum and place the data
values in a tuple following the % operator. The form of the second version of this operation 15
follows:
<format string> % (<datum-1>, …, <datum-n>)
Armed with the format operation, the powers of 10 loop can now display the numbers in
nicely aligned columns. The first column is left-justified in a field width of 3, and the second
column is right-justified in a field width of 12.
>>> for exponent in range(7, 11):
print("%-3d%12d" % (exponent, 10 ** exponent))
7 10000000
8 100000000
9 1000000000
10 10000000000
The format information for a data value of type float has the form
%<field width>.<precision>f
where .<precision> is optional. The next session shows the output of a floating-point
number without, and then with, a format string:
>>> salary = 100.00
>>> print("Your salary is $" + str(salary))
Your salary is $100.0
>>> print("Your salary is $%0.2f" % salary)
Your salary is $100.00
Here is another, minimal, example of the use of a format string, which says to use a field
width of 6 and a precision of 3 to format the float value 3.14:
>>> "%6.3f" % 3.14
' 3.140'
Note that Python adds a digit of precision to the number’s string and pads it with a space to
the left to achieve the field width of 6. This width includes the place occupied by the deci-
mal point.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
If you try to run a method that an object does not recognize, Python raises an exception
16 and halts the program. To discover the set of methods that an object recognizes, you
run Python’s dir function, in the Python shell, with the object’s type as an argument.
For example, dir(str) returns a list of the names of the methods recognized by string
objects. Running help(str.upper) prints documentation on the use of the method
str.upper.
Some method names, such as __add__ and __len__, are run when Python sees an object
used with certain operators or functions. Thus, for example:
len("greater") # Is equivalent to "greater".__len__()
"great" + "er" # Is equivalent to "great".__add__("er")
"e" in "great" # Is equivalent to "great".__contains__("e")
The reader is encouraged to explore the str methods with the dir and help functions.
Lists
A list is a sequence of zero or more Python objects, commonly called items. A list has a
literal representation, which uses square brackets to enclose items separated by commas.
Here are some examples:
[] # An empty list
["greater"] # A list of one string
["greater", "less"] # A list of two strings
["greater", "less", 10] # A list of two strings and an int
["greater", ["less", 10]] # A list with a nested list
Like strings, lists can be sliced and concatenated with the standard operators. However,
the results returned in this case are lists. Unlike strings, lists are mutable, meaning that you
can replace, insert, or remove items contained in them. This fact has two consequences.
First, the lists returned by the slice and concatenation operators are new lists, not pieces
of the original list. Second, the list type includes several methods called mutators, whose
purpose is to modify the structure of a list. You can enter dir(list) in a Python shell to
view them.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Built-In Python Collections and Their Operations
The most commonly used list mutator methods are append, insert, pop, remove, and sort.
Here are some examples of their use:
testList = [] # testList is []
testList.append(34) # testList is [34]
testList.append(22) # testList is [34, 22]
testList.sort() # testList is [22, 34]
17
testList.pop() # Returns 22; testList is [34]
testList.insert(0, 22) # testList is [22, 34]
testList.insert(1, 55) # testList is [22, 55, 34]
testList.pop(1) # Returns 55; testList is [22, 34]
testList.remove(22) # testList is [34]
testList.remove(55) # raises ValueError
The string methods split and join extract a list of words from a string and glue a list of
words together to form a string, respectively:
"Python is cool".split() # Returns ['Python', 'is', 'cool']
" ".join(["Python", "is", "cool"]) # Returns 'Python is cool'
You are encouraged to explore the list methods with the dir and help functions.
Tuples
A tuple is an immutable sequence of items. Tuple literals enclose items in parentheses.
A tuple is essentially like a list without mutator methods. However, a tuple with one item
must still include a comma, as follows:
>>> (34)
34
>>> (34,)
(34)
Note that Python treats the first expression, (34), as an integer enclosed in parentheses,
whereas the second expression, (34,), is treated as a new tuple of one item. For the avail-
able tuple methods, run dir(tuple) in the Python shell.
This is equivalent to but simpler than an index-based loop over the list:
testList = [67, 100, 22]
for index in range(len(testList)):
print(testList[index])
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
Dictionaries
A dictionary contains zero or more entries. Each entry associates a unique key with a value.
Keys are typically strings or integers, whereas values are any Python objects.
A dictionary literal encloses the key-value entries in a set of braces. Here are some
18 examples:
{} # An empty dictionary
{"name":"Ken"} # One entry
{"name":"Ken", "age":67} # Two entries
{"hobbies":["reading", "running"]} # One entry, value is a list
You use the subscript operator to access a value at a given key, add a value at a new key, and
replace a value at a given key. The pop method removes the entry and returns the value for
a given key. The keys method returns an iterable object over the keys, whereas the values
method returns an iterable object over the values. Like a list, a dictionary itself is an iterable
object, but the for loop iterates over a dictionary’s keys. The next code segment prints the
keys in a small dictionary:
>>> for key in {"name":"Ken", "age":67}:
print(key)
name
age
The reader is encouraged to explore the dict methods with the dir and help functions and
to experiment with dictionaries and their operations in a Python shell.
fourth variable, for further processing. Here is the code to accomplish this, using the sub-
script operator on colorTuple, which names the value returned by the color chooser:
rgbTuple = colorTuple[0]
hexString = colorTuple[1]
r = rgbTuple[0]
g = rgbTuple[1]
19
b = rgbTuple[2]
A pattern match uses an assignment of a structure to another structure of exactly the same
form. The target structure includes variables that will pick up the values at the correspond-
ing positions in the source structure. You can then use the variables for further processing.
Using pattern matching, you can accomplish this task in a single line of code, as follows:
((r, g, b), hexString) = colorTuple
Function Definitions
The syntax of a Python function definition is:
def <function name>(<list of parameters>):
<sequence of statements>
The rules and conventions for spelling function names and parameter names are the same
as for variable names. The list of required parameters can be empty or can include names
separated by commas. Again, unlike some other programming languages, no data types are
associated with the parameter names or with the function name itself.
Here is the definition of a simple function to compute and return the square of a number:
def square(n):
"""Returns the square of n."""
result = n ** 2
return result
Note the use of the string with triple quotes beneath the function header. This is a doc-
string. This string behaves like a comment within the function but also will be displayed
when the user enters help(square) at a Python shell prompt. Every function you define
should include a docstring that states what the function does and gives information about
any arguments or returned values.
Functions can introduce new variables, also called temporary variables. In the square
function, n is a parameter and result is a temporary variable. A function’s parameters and
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
temporary variables exist only during the lifetime of a function call and are not visible to
other functions or the surrounding program. Thus, several different functions may use the
same parameters and variable names without conflicts.
When a function does not include a return statement, it automatically returns the value
None after its last statement executes.
20
You can define functions in any order in a module, as long as no function is actually exe-
cuted before its definition has been compiled. The next example shows an illegal function
call at the beginning of a module:
first() # Raises a NameError (function undefined yet)
def first():
print("Calling first.")
second() # Not an error, because not actually
# called until after second is defined
def second():
print("Calling second.")
When Python runs the first line of code, function first has not yet been defined, so an
exception is raised. Were you to place a comment symbol # at the beginning of this line
and run the code again, the program would run to a normal termination. In this case, even
though function second appears to be called before it is defined, it is not actually called
until function first is called, by which time both functions have been defined.
You can specify parameters as optional, with default values, using the notation <parameter
name> = <default value>. Required parameters (those without default values) must
precede optional parameters in the parameter list.
Recursive Functions
A recursive function is a function that calls itself. To prevent a function from repeating
itself indefinitely, it must contain at least one selection statement. This statement examines
a condition called a base case to determine whether to stop or to continue with a recursive
step.
Let’s examine how to convert an iterative algorithm to a recursive function. Here is a
efinition of a function displayRange that prints the numbers from a lower bound to an
d
upper bound:
def displayRange(lower, upper):
"""Outputs the numbers from lower to upper."""
while lower <= upper:
print(lower)
lower = lower + 1
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Creating New Functions
How would you go about converting this function to a recursive one? First, you should note
two important facts:
•• The loop’s body continues execution while lower <= upper.
•• When the function executes, lower is incremented by 1 but upper never changes.
The equivalent recursive function performs similar primitive operations, but the loop is 21
replaced with an if statement and the assignment statement is replaced with a recursive
call of the function. Here is the code with these changes:
def displayRange(lower, upper):
"""Outputs the numbers from lower to upper."""
if lower <= upper:
print(lower)
displayRange(lower + 1, upper)
Although the syntax and design of the two functions are different, the same algorith-
mic process is executed. Each call of the recursive function visits the next number in the
sequence, just as the loop does in the iterative version of the function.
Most recursive functions expect at least one argument. This data value tests for the
base case that ends the recursive process. It is also modified in some way before each
recursive step. The modification of the data value should produce a new data value that
allows the function to eventually reach the base case. In the case of displayRange, the
value of the argument lower is incremented before each recursive call so that it eventu-
ally exceeds the value of the argument upper.
The next example is a recursive function that builds and returns a value. Python’s sum func-
tion expects a collection of numbers and returns their sum. This function should return the
sum of the numbers from a lower bound through an upper bound. The recursive ourSum
function returns 0 if lower exceeds upper (the base case). Otherwise, the function adds
lower to the ourSum of lower+ 1 through upper and returns this result. Here is the code for
this function:
def ourSum(lower, upper):
"""Returns the sum of the numbers from lower thru upper."""
if lower > upper:
return 0
else:
return lower + ourSum(lower + 1, upper)
The recursive call of ourSum adds the numbers from lower + 1 through upper. The func-
tion then adds lower to this result and returns it.
To get a better understanding of how recursion works, it is helpful to trace its calls. You
can do that for the recursive version of the ourSum function. You add an argument for a
margin of indentation and a print statement to trace the two arguments and the value
returned on each call. The first statement on each call computes the indentation, which
is then used in printing the two arguments. The value computed is also printed with
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
this indentation just before each call returns. Here is the code, followed by a session
showing its use:
def ourSum(lower, upper, margin = 0):
"""Returns the sum of the numbers from lower to upper,
and outputs a trace of the arguments and return values
on each call."""
22
blanks = " " * margin
print(blanks, lower, upper) # Print the arguments
if lower > upper:
print(blanks, 0) # Print the returned value
return 0
else:
result = lower + ourSum(lower + 1, upper, margin + 4)
print(blanks, result) # Print the returned value
return result
Usage:
>>> ourSum(1, 4)
1 4
2 4
3 4
4 4
5 4
0
4
7
9
10
10
The displayed pairs of arguments are indented further to the right as the calls of
urSum proceed. Note that the value of lower increases by 1 on each call, whereas
o
the value of upper stays the same. The final call of ourSum returns 0. As the recursion
unwinds, each value returned is aligned with the arguments above it and increases
by the current value of lower. This type of tracing can be a useful debugging tool for
recursive functions.
if n == 1: return product
else: return recurse(n - 1, n * product)
return recurse(n, 1)
# Second definition
def factorial(n, product = 1): 23
"""Returns the factorial of n."""
if n == 1: return product
else: return factorial(n - 1, n * product)
Higher-Order Functions
Python functions are first-class data objects. This means you can assign them to variables,
save them in data structures, pass them as arguments to other functions, and return them
as the values of other functions. A higher-order function is a function that receives another
function as an argument and applies it in some way. Python includes two built-in higher-
order functions, map and filter, that are useful for processing iterable objects.
Suppose you want to convert a list of integers to another list of the string representations of
those integers. You could use a loop to visit each integer, convert it to a string, and append
it to a new list, as follows:
newList = []
for number in oldList: newList.append(str(number))
Alternatively, you can use the map function. This function expects a function and an iterable
object as arguments and returns another iterable object wherein the argument function is
applied to each item contained in the iterable object. In short, map essentially transforms
each item in an iterable object. Thus, the code
map(str, oldList)
creates the iterable object containing the strings, and the code
newList = list(map(str, oldList))
Alternatively, you can use the filter function. This function expects a Boolean function
and an iterable object as arguments. The filter function returns an iterable object in
which each item is passed to the Boolean function. If this function returns True, the item
is retained in the returned iterable object; otherwise, the item is dropped from it. In short,
filter essentially keeps the items that pass a test in an iterable object. Thus, assuming the
programmer has already defined the Boolean function isPositive, the code
filter(isPositive, oldList)
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
creates the iterable object containing the non-zero grades, and the code
newList = list(filter(isPositive, oldList))
Note that the expression cannot include a sequence of statements, as in other Python
functions. The code
newList = list(filter(lambda number: number > 0, oldList))
uses an anonymous Boolean function to drop the zero grades from the list of grades.
Another high-order function, functools.reduce, boils an iterable object’s items down to a
single value by applying a function of two arguments to each next item and the result of the
previous application. Thus, the for loop to compute the product of a sequence of numbers
shown earlier can be rewritten as:
import functools
product = functools.reduce(lambda x, y: x * y, range(1, 11))
Catching Exceptions
When the Python virtual machine encounters a semantic error during program
execution, it raises an exception and halts the program with an error message. Examples
of semantic errors are undefined variable names, attempts to divide by 0, and list indices
out of range. The signaling of such errors is a boon to the programmer, who can then
correct them to produce a better program. However, some errors, such as bad digits in
an input number, are users’ mistakes. In these cases, the program should not allow the
resulting exceptions to halt execution but should trap these and allow the user to recover
gracefully.
Python includes a try-except statement that allows a program to trap or catch exceptions
and perform the appropriate recovery operations. Here is the syntax of the simplest form of
this statement:
try:
<statements>
except <exception type>:
<statements>
When you run this statement, the statements within the try clause are executed. If one
of these statements raises an exception, control is immediately transferred to the except
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Files and Their Operations
clause. If the type of exception raised matches the type in this clause, its statements
are executed. Otherwise, control is transferred to the caller of the t ry-except
statement and further up the chain of calls, until the exception is successfully handled
or the program halts with an error message. If the statements in the try clause raise
no exceptions, the except clause is skipped and control proceeds to the end of the
ry-except statement.
t
25
In general, you should try to include the exception type that matches the type of exception
expected under the circumstances; if no such type exists, the more general Exception type
will match any exception that happens to be raised.
The following demo program defines a recursive function called safeIntegerInput. This
function traps a ValueError exception that is raised if the user enters bad digits during
input. The function forces the user to continue until a well-formed integer is entered,
whereupon the integer is returned to the caller.
"""
Author: Ken Lambert
Demonstrates a function that traps number format errors during input.
"""
def safeIntegerInput(prompt):
"""Prompts the user for an integer and returns the
integer if it is well-formed. Otherwise, prints an
error message and repeats this process."""
inputString = input(prompt)
try:
number = int(inputString)
return number
except ValueError:
print("Error in number format:", inputString)
return safeIntegerInput(prompt)
if __name__ == "__main__":
age = safeIntegerInput("Enter your age: ")
print("Your age is", age)
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Chapter 1 Basic Python Programming
when examined with a text editor. Note that this format includes a space or a newline as a
separator of items in the text.
All data output to or input from a text file must be strings. Thus, numbers must be con-
verted to strings before output, and these strings must be converted back to numbers after
input.
You can output data to a text file using a file object. Python’s open function, which expects
a file pathname and a mode string as arguments, opens a connection to the file on disk and
returns a file object. The mode string is 'r' for input files and 'w' for output files. Thus, the
following code opens a file object on a file named myfile.txt for output:
>>> f = open("myfile.txt", 'w')
If the file does not exist, it is created with the given pathname. If the file already exists,
Python opens it. When data are written to the file and the file is closed, any data previously
existing in the file are erased.
String data are written (or output) to a file using the method write with the file object. The
write method expects a single string argument. If you want the output text to end with a
newline, you must include the escape character \n in the string. The next statement writes
two lines of text to the file:
>>> f.write("First line.\nSecond line.\n")
When all the outputs are finished, the file should be closed using the method close, as
follows:
>>> f.close()
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Files and Their Operations
The next code segment illustrates the output of integers to a text file. Five hundred random
integers between 1 and 500 are generated and written to a text file named integers.txt. The
newline character is the separator.
import random
f = open("integers.txt", 'w')
for count in range(500): 27
number = random.randint(1, 500)
f.write(str(number) + "\n")
f.close()
There are several ways to read data from an input file. The simplest way is to use the file
method read to input the entire contents of the file as a single string. If the file contains
multiple lines of text, the newline characters will be embedded in this string. The next
session with the shell shows how to use the method read:
>>> text = f.read()
>>> text
'First line.\nSecond line.\n'
>>> print(text)
First line.
Second line.
After input is finished, another call to read returns an empty string, to indicate that the end
of the file has been reached. To repeat an input, you must reopen the file. It is not necessary
to close the file.
Alternatively, an application might read and process the text one line at a time. A for loop
accomplishes this nicely. The for loop views a file object as a sequence of lines of text.
On each pass through the loop, the loop variable is bound to the next line of text in the
sequence. Here is a session that reopens the example file and visits the lines of text in it:
>>> f = open("myfile.txt", 'r')
>>> for line in f:
print(line)
First line.
Second line.
Note that print appears to output an extra newline. This is because each line of text input
from the file retains its newline character. You can drop this newline from the output by
using the optional argument to the print function shown earlier.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. Due to electronic rights, some third party content may be suppressed from the eBook and/or eChapter(s).
Editorial review has deemed that any suppressed content does not materially affect the overall learning experience. Cengage Learning reserves the right to remove additional content at any time if subsequent rights restrictions require it.
Exploring the Variety of Random
Documents with Different Content
wounding the other in the head. A short time after, our small-arm
ammunition magazine near No. 10 Battery caught fire.
About six o’clock bullets began to whistle over our heads in No.
13, and, my trumpeter being wounded, I took him myself into the
bomb-proof to be attended to. On the left flank men in yellow
jackets[30] were moving about in groups, and five minutes had not
passed before Second-Lieutenant Sadykov came into the shelter and
reported that the left flank was retreating. I rushed out and saw that
the yellow-coats were streaming up, and shrapnel bursting over the
7th and 5th Companies, while a heavy cross fire was being kept up.
The Japanese skirmishers had lain down in their places and there
was no warning of their sudden advance. Seeing that our scouts
were retreating, and that all the others might retreat with them, I,
not having any orders to retreat from the position, galloped off to
the reserve and ordered the one-and-a-half companies of the 14th
Regiment, sent by General Fock, to move against the Japanese
appearing near Work No. 10. As we rode down, we came into a hot
fire from the neighbouring hills.
The order to attack was given by me, for the commander of the
reserve rushed up to me and asked: “What are we to do?” “Attack,” I
answered, and pointed out to him whom to attack and where. After
that I galloped after the retreating soldiers and made myself hoarse
shouting “Stop, stop, my men!” But they in their turn shouted out to
me: “Your Excellency, we have been ordered to retreat.” I could not
imagine who had given this order. As, however, at this moment the
Japanese saw us retreating from behind the Nan Shan hills, and
opened a terrific shrapnel fire, it was absolutely impossible to stop
the men. A shrapnel bullet struck my mare’s ear and wellnigh
maddened her. I managed to rally my men in a position in rear,
chosen earlier by me, about a verst from the Nan Shan hills, and
when they had halted, I looked back towards the hills and saw two
bodies of men running down into the valley; they were probably the
5th and 7th Companies.
No. 13 was in the hands of the Japanese, who were to be seen on
the heights above, firing down on the retreating men, who quickly
hid themselves in the deep ravines. I now occupied the above-
mentioned position in rear, brought up a battalion of the 14th
Regiment, and lengthened the line as far as Ta-fang-shen station. I
found the battalion in question in a ravine behind the position. Of
the rest of the 14th Regiment I saw no signs; probably they were
somewhere in rear under cover. The commander of our scouts came
in to me here with our colours.
Night had set in, when the 14th and 5th Regiments received the
order to retire, and I, leaving some mounted patrols to watch the
enemy’s movements, went with the Mounted Scouts to Nan-kuan-
ling. While moving along the road, I met our 7th Company and saw
the whole of the 4th Division encamped in the wide valley. There I
found the companies of the 5th Regiment which had retreated, and
ordered them to report their losses. Very many of our comrades did
not answer the roll-call, the first return showing a loss in killed and
wounded of 75 officers and 1,500 men. It was awful to see the
thinned ranks of my gallant regiment; my heart bled for my officers,
who had brought up the rear in the retreat, but the spirit of those
left seemed to be as fine as ever. I feel bound to pay tribute to our
comrades who fell in the battle and mention some of their heroic
deeds.
The whole of the left flank attributed the retirement to the receipt
of an order, and consequently I set to work to sift the matter to the
bottom. About six o’clock General Fock sent an officer with the order
to retire. Though he did not come to me personally, this officer
probably sent an orderly—who failed to reach me—and himself went
to the left flank and conveyed the order to retire to the scout
detachments of the 13th and 14th Regiments. This order reached
the commander of the 7th Company through Second-Lieutenant
Merkoulev, besides which the former saw the orderly on a black
horse shouting and waving his sword towards the rear, and only then
ordered his company to retire. The fact that this order to retreat was
given, was confirmed by all the officers and men, and also by Ensign
Kaminar (5th Regiment).
When those who had been in Port Arthur were assembled in St.
Petersburg from all over the Empire to give evidence at General
Stessel’s trial, I only gave details of the Nan Shan fight in answering
the questions put to me. The conclusion arrived at was this: the
scout detachments of the 14th Regiment, shaken by the hasty
retirement of those of the 13th Regiment at that moment, began to
abandon their trenches about four o’clock, the time when I saw
them retreating in a body. Lieutenant Roosoi had only ten men left in
the trench, but the other companies—i.e., the 7th and 5th of our
regiment, and Captain Rotaiski’s company—remained on the
position. Lieutenant Glieb-Koshanski and the orderly galloped up
with a report to General Fock just as I was leaving No. 13 and had
mounted my horse, and it was thus quite possible for the orderly on
the black horse to have really galloped up to the position and given
the order to retire before I had stopped the retreating scouts.
Anyway, it was proved conclusively that the Japanese appeared in
No. 10 Battery, and the other inner works of the position before the
7th and 5th Companies began their retreat.
And it was in this way. When the Scout Detachment of the 13th
Regiment, under Second-Lieutenant Bandaletov, and part of the
Scouts of the 14th Regiment began to retire (in consequence of the
flanking fire from the gunboats, and not because of the rifle fire of
the Japanese, whose skirmishers did not come closer than 600
yards), the enemy, taking advantage of natural cover, pursued them
and, passing along the ravines and watercourses, occupied the
trenches we had vacated, together with No. 10 Battery and farther
points. As, however, the Japanese were not in great numbers, they
could not break through the centre, the 5th Company being in the
deep ravine, the 6th in No. 8 Redoubt, and Rotaiski’s company in a
deep valley. These companies could not have let the Japanese pass,
and I repeat that the Japanese lines were in full view from where I
was and did not move until the scouts appeared in our rear.
From accounts given by officers, this is what happened on the
right flank. After the attack on the 8th and 4th Companies had
failed, the enemy kept up a furious gun and rifle fire, but did not
approach our trenches. This continued until the retreat of the 5th
and 7th Companies had actually begun. When the retreat of the left
flank was noticed from No. 8 Redoubt, and the Japanese began to
sweep our right flank from No. 5, Major Goosov assembled all the
officers there for a consultation as to what should be done. After
some hesitation it was decided to retreat; and word of that decision
was sent to other companies. However, the 4th and 8th Companies,
remembering the order that there would be no retreat, refused to
act on the decision. Our gallant Colonel Bielozor was in command,
the company commanders being Captain Shastin of the 4th
Company, and Captain Makoveiev of the 8th. On the retirement of
the 6th Company from No. 8 Redoubt, the 3rd, 4th, 8th, and part of
the 12th Companies, found themselves in a hopeless position. There
were Japanese in their rear, Japanese machine guns on No. 5, and a
large body of Japanese in front, ready to attack, which they soon
did. Seeing their comrades on the heights, where our batteries had
been, and also in No. 8 Redoubt, the enemy in front advanced to the
attack, but our gallant companies momentarily stopped their
desperate rush by a volley, which covered the ground with hundreds
of the enemy’s killed and wounded. Then, facing round on the
enemy who was attacking their rear, they compelled him to take
cover behind the hills. The Japanese on the hill signalled with white
handkerchiefs to the companies to surrender, but they only received
volleys in reply. Taking advantage of the indecisive action of the
Japanese in their rear, Lieutenant-Colonel Bielozor decided to try and
extricate his men from this unequal fight, and gave the order to
retire. Under a heavy fire the men moved along the trenches to the
rear of the position, suffering severely from the marksmen on the
hills. In some places the men had to come up out of the trenches,
which were filled with dead and dying, but eventually the companies
succeeded in reaching No. 1 Battery. From that point, too,
Lieutenant-Colonel Bielozor and Captain Shastin saw some Japanese
columns trying to cut off our companies retreating from the centre
of the position.
The enemy was advancing from the shores of Hand Bay. Our
brave officers at once thought of covering our men by preventing
this turning movement, in spite of the enemy posted on the hills,
and to this end they collected their men, stopped them, and opened
volley fire on the Japanese. The latter retaliated, and in their turn
poured in a hot fire from rifles and machine guns. This fearful
struggle continued for some time until not a single one of our men
was left alive. They all fell in this unequal fight, defending
themselves finally not only with their bayonets, but even with their
fists. Lieutenant-Colonel Bielozor lost consciousness from loss of
blood, and fell; while Captain Shastin also fell, dangerously wounded
in the chest. Both were picked up by the Japanese Red-Cross men,
and saved, thanks to a Japanese officer, who gave orders that they
were not to be killed.[31] Our right flank retreated simultaneously
with our left at the moment when the Japanese began to enfilade
them from the hills.
If, however, General Fock had decided to attack the left flank of
the enemy, where they were already running out of shell and were
engaged with our companies, with even his two regiments, and had
brought up the whole of his artillery against this flank, the enemy
would, without doubt, have been checked and the victory might
have been on our side.
It is said that at the court-martial General Fock stated that he
wished to attack. What a pity that this wish came too late!
One must watch for the first sign of wavering in the soldier in
order to be able to judge the proper moment for throwing in the
reserves, instead of keeping them miles behind the firing line, as
seems necessary according to General Fock’s principle—“Keep back
your reserves as long as you possibly can, as they are always asked
for and sent up too early.” That is all right as far as it goes, but at
the same time reserves must be used exactly at the right moment. I
understand the meaning of this principle, but in order not to be
misled in adopting it, it is essential to follow the course of the action
very closely.
I had hardly gone two versts from the bivouac, when we heard firing
behind us. A moment afterwards a vague noise reached us, soon
distinctly recognized as the rumbling of a baggage wagon. In
another minute it had rattled past us at full speed. Behind it galloped
a field battery scattering or destroying all that came in its way, and
after the battery came a hurtling mass of wagons, mounted men,
riderless horses, and unarmed men, and, to make matters worse,
somebody raised the alarming cry of “Japanese cavalry! Japanese
cavalry!”
The din and confusion were awful, and from the bivouacs behind
us shots and volleys were heard. Together with the other officers
near me I rushed to the rear of the column to restore order. I also
ordered our band to strike up a march, and, thank God, its martial
strains restored confidence among the fugitives—the noise ceased,
and the men became quite calm and collected.
All available articles of food in the buffet had been eaten before
our arrival, but I succeeded in getting some salt wherewith to
flavour my bread.
General Stessel called to the front all those wounded who had
remained in the ranks, in order to address them, and to bestow
praise and rewards in the shape of the Cross of St. George. There
were, however, so many of them (more than 300) that the general
thought it was impossible to get so many crosses; he therefore
ordered the doctor to inspect them and separate the badly from the
slightly wounded. There were sixty of the former category, and they
were given St. George’s crosses accordingly. These were the sole
recipients of rewards for the Nan Shan battle, those slightly
wounded receiving nothing for their bravery—and the number of
such was great.
I have already mentioned the fact that our men came away with
only their rifles, most of the tents and great-coats having been left
on the field of battle. It was fortunate that just before the battle we
had transported the bulk of our stores into Port Arthur, where they
had been deposited in Captain Preegorovski’s house, which had been
hired for the purpose. We brought all we wanted out of Port Arthur
without delay, and distributed the necessaries among the men. At
the same time we drove out with us a large herd of cattle,
amounting to about 200 head.
Unfortunately, the order was given when the enemy was already
in touch with us, but we managed to collect about 1,000 head and
drove them to the rear of the army, almost into Port Arthur.
After three days’ rest we moved into Port Arthur and stopped in a
village near Serotka Hill,[36] forming the reserve of the 4th Division,
which took up the position Shuang-tai-kou, Yu-pi-la-tzu, Chien Shan,
and Lao-tso Shan.[37]
VIEW OF THE COUNTRY AT THE POSITION OF THE PASSES. IN
THE DISTANCE ON THE LEFT ARE SEEN THE
PEAKS OF CHIEN SHAN.
p. 66]
During this time the 5th Regiment was divided into two parts, and
I was put in command of the left flank of the defence, and began to
fortify the position on 174 Metre Hill and the country in front of it, as
also the western side of Feng-huang Shan[38] from the Great
Mandarin road to Eight Ships’ Bay. Stationed along the shore of the
latter was Captain Sakatski’s detachment, and two other
detachments were on the banks of Louisa Bay, both under my
command, the former having with it four small naval guns under
Midshipman Doudkin.
Our 6th and 7th Companies occupied and fortified Feng-huang
Shan from the Great Mandarin road up to Major Sakatski’s
detachment. Our three scout detachments occupied and fortified the
174 Metre and Headquarter Hills, and also Height 426.[39] The 3rd
and 9th Companies occupied 174 Metre Hill, while the 2nd and 4th
held 203 Metre Hill. They all worked hard at their fortifications under
the supervision of their officers, in accordance with orders given by
me.
I detailed two companies of the 7th Division for this work, utilizing
all the material we could find in the town. Having no sapper officer
with me, I had personally to supervise everywhere—on the
advanced positions as well as in the town. It was a great help that
the officers of the 5th Regiment were, thanks to constant practice,
excellent sappers.
We could only obtain tools with great difficulty and from various
sources. Most of them we got from Colonel Grigorenko, commanding
the Engineers in the fortress, and from the railway authorities.
The number of men given me to carry out the work which I had
been ordered to do was insufficient, so I asked if I could employ the
whole of my regiment. I received permission early in June, and
moved the regimental staff to Division Hill, where we made
ourselves very snug, pitching a huge marquee and getting our field
kitchen into working order.
From the moment of his first coming into touch with us, at the
beginning of May, till July 26, he pressed our right flank, and
compelled us to change our position, and on the 26th commenced
his attack on the entire hill section.
The 3rd Battalion had to bear the brunt of the retreat from Lao-
tso Shan, since, as had been expected, the mixed companies on the
right flank did not distinguish themselves when it came to fighting.
When the enemy began his decisive attack on the 26th, I was
moved up with the 1st Battalion, which was then commanded by
Major Stempnevski (sen.), a splendid all-round officer. I arrived with
my battalion in the morning and found all our commanders with the
divisional staff—Generals Stessel, Fock, and Kondratenko. The battle
was raging along the whole line.
As all the positions were divided into sections, and each section
had its commander, I was free to become a spectator of all that was
going on. We went by train to 11th Verst, and had only just got
down out of the carriages, when the 1st Scout Detachment, under
Lieutenant Kostoushko, was ordered to move on Yu-pi-la-tzu Hill,
where the defenders had been decimated by the ceaseless artillery
fire.
The 1st Battalion was then moved to the Shipinsin Pass, where,
judging by the artillery fire, a determined attack was in preparation,
and only our 7th and 8th Companies were left with the regimental
staff.
The fighting of July 26 and 27 did not cost us very dearly, except
for severe wounds received by Lieutenant Kostoushko (a wound in
the chest, and a number of other wounds in the left shoulder and
side). This officer had thrown himself, with a part of his scouts, on
the enemy, who had already seized some of our trenches on Yu-pi-
la-tzu Hill. This was on the night of July 27–28.
On the 27th the battle was again renewed along the whole line.
Lao-tso Shan was swept by the fire of very heavy guns—probably 6-
inch, judging from the size of the shell bursts. It was very difficult
for our artillery to cope with these guns, as they were not only very
far off, but also well concealed.
Our battery on the pass itself was literally swept with Japanese
shell, and there was a continuous roar of musketry fire, under which
our men were, however, perfectly calm, and even joked about the
bad shooting of the Japanese gunners. Though this went on all day,
the defence stood firm the whole time.
Our 1st Battalion had not yet come into action, but was to be seen
as a black spot near a zigzag in the road leading to the Shipinsin
Pass.
General Fock met us below, and at once gave General Stessel full
details of all that had taken place. Our men had stood firm
everywhere, except on Yu-pi-la-tzu Hill, where things were going
badly with us. It was a physical impossibility to hold on there, in
spite of the new trenches, on account of the artillery fire
concentrated on the hill. Hence it was decided to abandon Yu-pi-la-
tzu, and orders were sent there accordingly.
When this decision had been arrived at, General Fock said, in his
short, sharp way of speaking: “Well, it is impossible to hold on to Yu-
pi-la-tzu. It would entail too heavy losses. Even if the companies
there left it of their own accord, it would be nothing serious; but to
give up Lao-tso Shan, that would be a disgrace, almost amounting to
treachery.” He had only just said this, when news came that Lao-tso
Shan had been evacuated by the troops holding it. “Now we shall
have to make a general retreat,” said General Fock, and he gave
orders to retire and to take up a new position with the right flank at
Ta-ku Shan—the centre near 11th Verst, and the left on Feng-huang
Shan.
It is obvious from the foregoing details that the retreat from Lao-
tso Shan was made in perfect order.
On the morning of the 26th the Japanese opened a heavy gun fire
on our positions, followed by a vigorous attack, but they obtained no
hold anywhere that day, as our men held on to their positions and
beat them back at every point.
On the 27th the Japanese repeated their attacks, but had no more
success than on the preceding day, whereupon they proceeded to
make a night attack.
The Japanese rushed into the gap thus created, and, working
round to the rear, began to pour a flanking fire into the other
companies, who were ignorant of what had happened, and had
remained in their positions. Taken by surprise, these companies lost
their heads in turn and retreated, also without informing their
neighbours. In this manner the gap grew rapidly until it extended to
Colonel Dounin’s troops, when the following became the position of
affairs:
The 9th Company and 3rd Scout Detachment of the 5th Regiment
occupied the valley, being in touch on the right with the 11th
Company 27th Regiment. The 3rd Scout Detachment formed the
outpost line, with the 9th in reserve behind it.
ebooksecure.com