Skip to content

Commit d930e40

Browse files
committed
Proofed book.
1 parent 8d761bc commit d930e40

15 files changed

+190
-101
lines changed

‎doc/source/0_preface.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ The assumptions underpinning this approach seem to be some combination of a
2222
belief that maths degrees should only teach maths, as well a feeling that the
2323
mathematical algorithms are some how the difficult part and that programming is
2424
a mere technical skill that students will somehow pick up along the way. The
25-
regrettable consequence of this approach is that many maths students and
26-
graduates end up without the programming, software development, and debugging
27-
skills that they need to make effective use of computers in their further
28-
studies or working careers.
25+
consequence of this approach is that many maths students and graduates end up
26+
without the programming, software development, and debugging skills that they
27+
need to make effective use of computers in their further studies or working
28+
careers.
2929

3030
What is this book for?
3131
----------------------

‎doc/source/2_programs_in_files.rst

+29-21
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,12 @@ packages come in. A Python package is a collection of module files,
424424
which can be imported together. The basic folder structure of a Python
425425
package is shown in :numref:`package-layout`.
426426

427+
.. only:: book
428+
429+
.. raw:: latex
430+
431+
\clearpage
432+
427433
.. _package-layout:
428434

429435
.. code-block::
@@ -649,15 +655,13 @@ There is one more feature of Pip packages that it is useful to introduce at
649655
this stage: dependencies. If you write a package and the modules in that
650656
package themselves import other packages, then a user will need those packages
651657
to be installed in their Python environment, or your package will not work. If
652-
those packages form part of the Python :ref:`Standard Library <library-index>`
653-
then you need do nothing at all since they will automatically be available.
654-
However, if your package depends on other packages that need to be installed
655-
from PyPI then steps need to be taken to ensure that your users will have the
656-
correct packages installed. The `install_requires` keyword argument to
657-
:func:`setuptools.setup` takes a list of Pip package names. Pip will install
658-
any of these packages that are not already available before installing the
659-
package itself. :numref:`dependency-setup-py` illustrates this by adding a
660-
dependency on :mod:`numpy`.
658+
your package depends on other packages that need to be installed from PyPI then
659+
steps need to be taken to ensure that your users will have the correct packages
660+
installed. The `install_requires` keyword argument to :func:`setuptools.setup`
661+
takes a list of Pip package names. Pip will install any of these packages that
662+
are not already available before installing the package itself.
663+
:numref:`dependency-setup-py` illustrates this by adding a dependency on
664+
:mod:`numpy`.
661665

662666
.. _dependency-setup-py:
663667

@@ -675,11 +679,15 @@ dependency on :mod:`numpy`.
675679
676680
.. warning::
677681

678-
`install_requires` should only list packages that Pip can install from
679-
PyPI. In particular, packages from the built-in Python Standard Library
680-
must not be listed in `install_requires`. Listing these packages is
681-
unnecessary, since they are guaranteed to be available, and will cause an
682-
error because Pip will attempt (and fail) to install them from PyPI.
682+
`install_requires` should not list packages from the Python Standard
683+
Library. These are always available, and listing them will cause Pip to error.
684+
685+
686+
.. `install_requires` should only list packages that Pip can install from
687+
.. PyPI. In particular, packages from the built-in Python Standard Library
688+
.. must not be listed in `install_requires`. Listing these packages is
689+
.. unnecessary, since they are guaranteed to be available, and will cause an
690+
.. error because Pip will attempt (and fail) to install them from PyPI.
683691
684692
Testing frameworks
685693
------------------
@@ -947,11 +955,6 @@ already familiar with Git and GitHub then you will also need to work through
947955
.. you will use for this course on your computer. Start with an overall folder
948956
.. for the module, and create a virtual environment in that module.
949957
950-
.. only:: book
951-
952-
.. raw:: latex
953-
954-
\clearpage
955958
956959
.. _course_repo:
957960

@@ -1030,8 +1033,13 @@ already familiar with Git and GitHub then you will also need to work through
10301033
After this and every exercise in which you write code, ensure that you
10311034
add any new files to Git, commit all of your changes, and push to
10321035
GitHub. Then ensure that the tests pass on GitHub. For more information
1033-
about how to do any of these, refer back the :ref:`Faculty of Natural Sciences
1034-
Git instructions <github_classroom_exercise>`.
1036+
about how to do any of these, refer to :numref:`Appendix %s <git>`.
1037+
1038+
.. only:: book
1039+
1040+
.. raw:: latex
1041+
1042+
\clearpage
10351043

10361044
.. proof:exercise::
10371045

‎doc/source/4_style.rst

+12-6
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ activated your :term:`virtual environment` and then run:
143143

144144
.. code-block:: console
145145
146-
(my_venv) $ python -m pip install flake8
146+
(PoP_venv) $ python -m pip install flake8
147147
148148
This is enough to run Flake8 on the command line, however you will probably want
149149
to set up your editor to highlight flake8 incompatibilities in your source. For
@@ -299,14 +299,14 @@ White space within lines
299299

300300
.. code-block:: python3
301301
302-
my_function (1) # Space between function name and bracket.
302+
sin (1) # Space between function name and bracket.
303303
x [0] # Space before index square bracket.
304304
305305
.. container:: goodcode
306306

307307
.. code-block:: python3
308308
309-
my_function(1)
309+
sin(1)
310310
x[0]
311311
312312
3. Put a space after a comma but not before it, exactly like you would
@@ -537,14 +537,14 @@ function, variable, and module names
537537

538538
.. code-block:: python3
539539
540-
def Euler # Don't capitalise function names.
540+
def Euler(n): # Don't capitalise function names.
541541
MaxRadius = 10. # No CamelCase.
542542
543543
.. container:: goodcode
544544

545545
.. code-block:: python3
546546
547-
def euler # Lower case, even for names.
547+
def euler(n): # Lower case, even for names.
548548
max_radius = 10. # Separate words with _.
549549
550550
method parameters
@@ -1036,7 +1036,8 @@ a full stop.
10361036
.. code-block:: python3
10371037
10381038
def fib(n):
1039-
"Return the n-th Fibonacci number" # Single quotes, no full stop.
1039+
"Return the n-th Fibonacci number" # Single quotes,
1040+
# no full stop.
10401041
10411042
def fib(n):
10421043
"""Returns the n-th Fibonacci number.""" # Sentence not
@@ -1336,6 +1337,11 @@ neverending sequence of gliders:
13361337

13371338
Gliders rotated by 1, 2, and 3 right angles anticlockwise.
13381339

1340+
.. only:: book
1341+
1342+
.. raw:: latex
1343+
1344+
\clearpage
13391345

13401346
.. proof:exercise::
13411347

‎doc/source/6_exceptions.rst

+6
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ occurs. Consider the following code:
107107
a = (1, 2
108108
print(a)
109109
110+
.. only:: book
111+
112+
.. raw:: latex
113+
114+
\clearpage
115+
110116
The error here is a missing closing bracket on the first line, however
111117
the error message which the :term:`Python interpreter` prints when this code is run is:
112118

‎doc/source/7_inheritance.rst

+14-2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ a :term:`class`, :func:`issubclass` will tell us when one
5959
In [5]: issubclass(int, Number)
6060
Out[5]: True
6161
62+
.. only:: book
63+
64+
.. raw:: latex
65+
66+
\clearpage
67+
6268
In fact, there is a whole hierarchy of
6369
numeric types in :mod:`numbers`:
6470

@@ -322,7 +328,7 @@ follows:
322328
:linenos:
323329
324330
class GeneralLinearGroup:
325-
"""The general linear group represented by degree x degree matrices."""
331+
"""The general linear group represented by degree square matrices."""
326332
def __init__(self, degree):
327333
self.degree = degree
328334
@@ -351,7 +357,7 @@ follows:
351357
352358
def __repr__(self):
353359
"""Return the canonical string representation of the group."""
354-
return f"{type(self).__name__}({repr(self.degree)})"
360+
return f"{type(sxelf).__name__}({repr(self.degree)})"
355361
356362
We won't illustrate the operation of this class, though the reader is welcome to
357363
:keyword:`import` the :mod:`example_code.groups_basic` module and experiment.
@@ -593,6 +599,12 @@ than the current one with:
593599
Observe that since `type(self)` is a :term:`class`, we can :term:`instantiate`
594600
it by calling it.
595601

602+
.. only:: book
603+
604+
.. raw:: latex
605+
606+
\clearpage
607+
596608
Calling parent class methods
597609
----------------------------
598610

‎doc/source/8_debugging.rst

+38-17
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@ illustrated with an example.
4646
Richard,Mccoy,RM518
4747
Marjorie,Jackson,MJ1418
4848

49+
.. only:: book
50+
51+
.. raw:: latex
52+
53+
\clearpage
54+
4955
:numref:`student_data` shows the first few records in a table of student data.
50-
Having installed pandas:
56+
Having installed Pandas:
5157

5258
.. code-block:: console
5359
@@ -80,11 +86,23 @@ the following code enables us to access the data from within Python:
8086
In [6]: type(students['FirstName'])
8187
Out[6]: pandas.core.series.Series
8288
83-
Observe that the :class:`~pandas.DataFrame` acts as a dictionary of
84-
one-dimensional data :class:`~pandas.Series`. A :class:`pandas.Series` can be
85-
indexed and sliced like any other Python :ref:`sequence type <typesseq>`. This
86-
very high level introduction is all we'll need to use pandas in demonstrations
87-
in this chapter. Much more documentation is available on the `pandas website <https://pandas.pydata.org/docs/>`__.
89+
.. only:: not book
90+
91+
Observe that the :class:`~pandas.DataFrame` acts as a dictionary of
92+
one-dimensional data :class:`~pandas.Series`. A :class:`pandas.Series` can be
93+
indexed and sliced like any other Python :ref:`sequence type <typesseq>`. This
94+
very high level introduction is all we'll need to use pandas in demonstrations
95+
in this chapter. Much more documentation is available on the `Pandas website <https://pandas.pydata.org/docs/>`__.
96+
97+
.. only:: book
98+
99+
Observe that the :class:`~pandas.DataFrame` acts as a dictionary of
100+
one-dimensional data :class:`~pandas.Series`. A :class:`pandas.Series` can be
101+
indexed and sliced like any other Python :ref:`sequence type <typesseq>`. This
102+
very high level introduction is all we'll need to use pandas in demonstrations
103+
in this chapter. Much more documentation is available on the
104+
Pandas website [#pandas]_.
105+
88106

89107
.. note::
90108

@@ -497,17 +515,17 @@ The recipe for hypothesis-based debugging runs something like the following:
497515
1. Hypothesis Formation
498516

499517
What statements would be true were this issue not occurring. For example:
500-
a. Are there variables which should have a known type or value, or would
501-
have a known type or value in response to a different input?
502-
b. Does it appear that particular code that should have run already has
503-
not, or code that should not run has run?
504-
c. Looking at a value which is observed to be wrong, where is the operation
505-
that computes that value? Does a. or b. apply to any of the inputs to
506-
that operation.
507-
508-
This process requires intuition and understanding of the problem. It is the
509-
least systematic part of the process. The following steps are much more
510-
systematic.
518+
a. Are there variables which should have a known type or value, or would
519+
have a known type or value in response to a different input?
520+
b. Does it appear that particular code that should have run already has
521+
not, or code that should not run has run?
522+
c. Looking at a value which is observed to be wrong, where is the operation
523+
that computes that value? Does a. or b. apply to any of the inputs to
524+
that operation.
525+
526+
This process requires intuition and understanding of the problem. It is the
527+
least systematic part of the process. The following steps are much more
528+
systematic.
511529

512530
2. Hypothesis testing
513531

@@ -907,6 +925,9 @@ Exercises
907925

908926
.. rubric:: Footnotes
909927

928+
.. [#pandas] `<https://pandas.pydata.org/docs/>
929+
<https://pandas.pydata.org/docs/>`__
930+
910931
.. [#ufl] `https://github.com/object-oriented-python/ufl
911932
<https://github.com/object-oriented-python/ufl>`__
912933

‎doc/source/9_trees_and_directed_acyclic_graphs.rst

+12-11
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ We'll consider postorder traversal first, as it's the easier to implement.
395395
tree: TreeNode
396396
The tree to be visited.
397397
fn: function(node, *fn_children)
398-
A function to be applied at each node. The function should take the
399-
node to be visited as its first argument, and the results of
398+
A function to be applied at each node. The function should take
399+
the node to be visited as its first argument, and the results of
400400
visiting its children as any further arguments.
401401
"""
402402
return fn(tree, *(postvisitor(c, fn) for c in tree.children))
@@ -480,8 +480,8 @@ call :func:`previsitor` on the child nodes.
480480
tree: TreeNode
481481
The tree to be visited.
482482
fn: function(node, fn_parent)
483-
A function to be applied at each node. The function should take the
484-
node to be visited as its first argument, and the result of
483+
A function to be applied at each node. The function should take
484+
the node to be visited as its first argument, and the result of
485485
visiting its parent as the second.
486486
"""
487487
fn_out = fn(tree, fn_parent)
@@ -776,7 +776,8 @@ function.
776776
Any keyword arguments required to evaluate specific types of
777777
expression.
778778
symbol_map: dict
779-
A dictionary mapping Symbol names to numerical values, for example:
779+
A dictionary mapping Symbol names to numerical values, for
780+
example:
780781
781782
{'x': 1}
782783
"""
@@ -819,24 +820,24 @@ function.
819820
return o[0] ** o[1]
820821
821822
Next we turn our attention to the implementation of evaluation for the different
822-
expression types. Look first at lines 27-29, which provide the evaluation of
823+
expression types. Look first at lines 28-30, which provide the evaluation of
823824
:class:`Number` nodes. The function body is trivial: the evaluation of a
824825
:class:`Number` is simply its value. The function interface is more interesting.
825826
Notice that the function name is given as `_`. This is the Python convention for
826827
a name which will never be used. This function will never be called by its
827-
declared name. Instead, look at the decorator on line 27. The single dispatch
828+
declared name. Instead, look at the decorator on line 28. The single dispatch
828829
function :func:`~example_code.expression_tools.evaluate` has a :term:`method`
829830
:meth:`register`. When used as a decorator, the :meth:`register` method of a
830831
single dispatch function registers the function that follows as implementation
831832
for the :keyword:`class` given as an argument to :meth:`register`. On this
832833
occasion, this is :class:`expressions.Number`.
833834

834-
Now look at lines 32-34. These contain the implementation of
835+
Now look at lines 33-35. These contain the implementation of
835836
:func:`~example_code.expression_tools.evaluate` for :class:`expressions.Symbol`.
836837
In order to evaluate a symbol, we depend on the mapping from symbol names to
837838
numerical values that has been passed in.
838839

839-
Finally, look at lines 37-39. These define the evaluation visitor for addition.
840+
Finally, look at lines 38-40. These define the evaluation visitor for addition.
840841
This works simply by adding the results of evaluating the two operands of
841842
:class:`expressions.Add`. The evaluation visitors for the other operators
842843
follow in an analogous manner.
@@ -869,8 +870,8 @@ function.
869870
expr: Expression
870871
The expression to be visited.
871872
fn: function(node, *o, **kwargs)
872-
A function to be applied at each node. The function should take the
873-
node to be visited as its first argument, and the results of
873+
A function to be applied at each node. The function should take
874+
the node to be visited as its first argument, and the results of
874875
visiting its operands as any further positional arguments. Any
875876
additional information that the visitor requires can be passed in
876877
as keyword arguments.

‎doc/source/_static/poptitle.sty

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
% }
6868
% %\rule{15mm,297mm}
6969
%\end{textblock}
70-
\begin{textblock}{175}(17.5,74.25)
70+
\begin{textblock}{154}(17.5,74.25)
7171
\setlength{\parskip}{2ex}
7272
{\sffamily\fontsize{25}{30}\selectfont\noindent\thetitle}
7373

@@ -83,7 +83,7 @@
8383
\mbox{}
8484
\pagebreak
8585

86-
\begin{textblock}{175}[0,1](17.5,230.5)
86+
\begin{textblock}{146}[0,1](17.5,230.5)
8787
{
8888
%\hypersetup{urlcolor=imperialblue}
8989
\sffamily\fontsize{12}{14}\selectfont

0 commit comments

Comments
 (0)