Skip to content

Commit a6cb013

Browse files
committedApr 17, 2025·
added literature, improved terms
1 parent 08c58d0 commit a6cb013

File tree

15 files changed

+151
-61
lines changed

15 files changed

+151
-61
lines changed
 

‎text/back/scripts.tex

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
In the scripts, we install tools if they are not yet installed.
3030
We then apply the tools to whatever the parameters of the scripts state.
3131
Now, in a real environment, a tool can either succeed or fail.
32-
A unit test executed with \pytest\ will fail and exit with a non-zero exit code if the test, well, fails.
32+
A \pgls{unitTest} executed with \pytest\ will fail and exit with a non-zero exit code if the test, well, fails.
3333
A static code analysis tool like \ruff\ will fail with a non-zero exit code if it discovers any issue with the code.
3434
However, our scripts invoking these tools will \emph{not} fail in such cases.
3535
They will collect the \pgls{exitCode} of the tool they are invoking and print it.
@@ -66,7 +66,7 @@
6666
It then applies \pylint\ to a the selected set of files, using a reasonable default configuration.
6767
\Cref{exec:loops:for_loop_no_enumerate:pylint} is an example of the output of this \pgls{linter}.
6868

69-
\Cref{lst:bash:pytest} is similarly structured, but instead of performing \emph{static} code analysis, it executes unit test cases.
69+
\Cref{lst:bash:pytest} is similarly structured, but instead of performing \emph{static} code analysis, it executes \pgls{unitTest} cases.
7070
The directory and list of \python\ files with the test cases are provided as command line arguments.
7171
This script checks if \pytest\ and its plugin \textil{pytest-timeout} are installed and, if not, installs them.
7272
It then executes the tests with a fixed ten second timeout that we use in this book.

‎text/front/preface/preface.tex

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ \chapter*{Preface}%
55
It aims to strike a good balance between theory and practice, leaning more to the practice side.
66
In particular, we try to teach programming together with some software engineering concepts.
77
It is the firm opinion of the author that these two cannot be separated.
8-
Teaching programming alone without introducing tools such as static code analysis, unit tests, and enforcing principles such as code style and proper commenting will create bad programmers.
8+
Teaching programming alone without introducing tools such as static code analysis, \pglspl{unitTest}, and enforcing principles such as code style and proper commenting will create bad programmers.
99
So we discuss these aspects while working our way through the principles of programming.
1010

1111
This book is intended to be read on an electronic device.

‎text/main/basics/collections/sets/sets.tex

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
So what is the advantage of sets?
4545
Sets are fast.
4646
In \python, sets are implemented based on the concept of hash tables and thus inherit the computational performance of these datastructures~\cite{K1998SAS,CLRS2009ITA,SKS2019DSC}.
47-
The operation for checking whether one object is contained in a set can be done in \bigOb{1} in average, whereas lists need \bigOb{n} in average, with $n$~being the list length~\cite{H2024PBOTTCODDSIPP33,B2023T,N2022CCSFPO}.
47+
The operation for checking whether one object is contained in a set can be done in \bigOb{1} in average, whereas lists need \bigOb{n} in average, with $n$~being the list length~\cite{H2025PM:PBOTTCODDSIPP33,B2023T,N2022CCSFPO}.
4848
This means that checking whether an element is contained in a set costs approximately a constant number of CPU cycles, whereas doing the same for a list takes a number of cycles roughly linear in the length of the list.
4949
Lists thus can be preferred if we either only have very few elements to check or if we need to access elements using integer indices.
5050
If we have more than just very few elements and/or need to perform set operations such as those discussed in the following text, sets are the way to go.%

‎text/main/basics/gettingStarted/gettingStarted.tex

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
You need a nice editor in which you can write the programs.
1111
Actually, you want an editor where you can not just write programs.
1212
You want an editor where you can also directly execute and test your programs.
13-
In software development, you often work with a \pgls{vcs} like \git.
13+
In software development, you often work with a \pgls{VCS} like \git.
1414
You want to do that convenient from your editor.
1515
Such an editor, which integrates many of the common tasks that occur during programming, is called an \pgls{ide}.
1616
In this book, we will use the \pycharm\ \pgls{ide}~\cite{VHN2023HOADWP,Y2022PPADT}.

‎text/main/basics/variables/typesAndTypeHints/typesAndTypeHints.tex

+20-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120
We use the \bash\ script given in \cref{lst:bash:mypy} on \cpageref{lst:bash:mypy} to apply \mypy\ to the example programs in this book.%
121121
}%
122122
%
123-
If we instead apply \mypy\ the completely fine (albeit useless) program \cref{lst:variables:types}, it will tell us that there is no error, as illustrated in \cref{exec:variables:variable_types:mypy}.
123+
If we instead apply \mypy\ to the completely fine (albeit useless) program \cref{lst:variables:types}, it will tell us that there is no error, as illustrated in \cref{exec:variables:variable_types:mypy}.
124124
So we now have one tool at our hands with which we can check our source code for type-related problems.
125125
Notice that this program just checks the source code.
126126
It does not change the code and it does not execute our program.
@@ -136,6 +136,25 @@
136136
Repeat this until no errors are found anymore.%
137137
}%
138138
%
139+
When reading the text, you may think:
140+
\mypy\ is an additional software.
141+
If I want to use it, I need to install it and I will have to learn its command line parameters.
142+
Everytime I do use it and apply it to some \python\ code, I need to open the \pgls{terminal}, go into the directory where my program code is located, run the \mypy\ program, and read the output.
143+
This is, like, lots of work.
144+
Why do I need to bother?
145+
There are two answers, the first one is \inQuotes{This will improve the quality of your code.}
146+
We elaborate this answer more later.
147+
But there also is a second answer:%
148+
%
149+
\bestPractice{manyTools}{%
150+
A professional software engineer or programmer or, actually, any professional computer scientist knows many tools and is always keen to learn new tools.%
151+
}%
152+
%
153+
In your professional life, you will learn dozens if not hundreds of tools on different \pglspl{OS}.
154+
The more tools you know, the easier it gets to learn and dig into other software if need be.
155+
Today, automated builds in \pgls{continuousIntegration}, for example, alone may involve more than a dozen programs.
156+
Being able to learning new tools and becoming proficient with them is thus an essential skill of a programmer.%
157+
%
139158
\endhsection%
140159
%
141160
\hsection{Type Hints}%

‎text/main/classes/dunder/dunder.tex

+3-3
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
Differently from lists, new elements are not added at the end.
212212
Instead, they would be more like lists of a fixed length where new elements are placed at specific indices where they can be found again.
213213
These hash tables~\cite{K1998SAS,CLRS2009ITA,SKS2019DSC} are very fast.
214-
They have an element-wise access/update time complexity of~\bigOb{1}~\cite{H2024PBOTTCODDSIPP33,B2023T,N2022CCSFPO}.
214+
They have an element-wise access/update time complexity of~\bigOb{1}~\cite{H2025PM:PBOTTCODDSIPP33,B2023T,N2022CCSFPO}.
215215
As you know, lists can be indexed by integers.
216216
Since we also want to be able to use objects that are \emph{not} integers as keys, too, we need a way to \inQuotes{translate} these objects to integers.
217217
That is what \dunder{hash} is supposed to do.
@@ -1590,7 +1590,7 @@
15901590
\label{fig:pythonDunder:3}%
15911591
\end{figure}%
15921592
%
1593-
Besides the examples mentioned above, there are many more duner methods in \python~\cite{H2024EDMIP}.
1593+
Besides the examples mentioned above, there are many more duner methods in \python~\cite{H2025PM:EDMIP}.
15941594
We can only provide an abridged overview in \cref{fig:pythonDunder:1,fig:pythonDunder:2,fig:pythonDunder:3}.
15951595
15961596
From \cref{fig:pythonDunder:1} we learn that there are three string representation dunder functions.
@@ -1661,7 +1661,7 @@
16611661
Finally, \cref{fig:pythonDunder:3} lists the dunder methods for operators such as~\pythonilIdx{\&}, \pythonil{|}\pythonIdx{\textbar}, \pythonil{\^}\pythonIdx{\textasciicircum}, \pythonil{>>}\pythonIdx{>\strut>}, and \pythonil{<<}\pythonIdx{<\strut<}, which we learned about when we first got in touch with integer numbers in~\cref{sec:int:bitstrings}.
16621662
These dunder methods follow the same schematic as those for arithmetics and also have \inQuotes{\pythonil{r}} and \inQuotes{\pythonil{i}}~variants.
16631663
1664-
Even more dunder methods are listed in the comprehensive overview~\cite{H2024EDMIP}.
1664+
Even more dunder methods are listed in the comprehensive overview~\cite{H2025PM:EDMIP}.
16651665
%
16661666
%\FloatBarrier%
16671667
\endhsection%

‎text/main/controlFlow/exceptions/exceptions.tex

+15-15
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
When we execute our programs, then there are at least two things that can go wrong.
88
On one hand, we can never really be sure that our program code is free of programming mistakes.
99
The larger a project gets, the more likely it is that there are some bugs hidden somewhere in the code.
10-
Thorough unit testing can reduce the likelihood of bugs, but it cannot entirely prevent them.
10+
Thorough \pglspl{unitTest} can reduce the likelihood of bugs, but it cannot entirely prevent them.
1111

1212
On the other hand, our programs do not exist all by themselves in a vacuum.
1313
They receive input, maybe from files, maybe from the user, maybe from sensors.
@@ -628,19 +628,19 @@
628628
\label{sec:testingExceptions}%
629629
%
630630
\gitPython{\programmingWithPythonCodeRepo}{exceptions/test_sqrt_raise.py}{--args format}{exceptions:test_sqrt_raise}{%
631-
A unit test checking that our new variant of the \pythonil{sqrt} function given in \cref{lst:exceptions:sqrt_raise} properly raises an \pythonilIdx{ArithmeticError} if its input is non-finite or negative.}%
631+
A \pgls{unitTest} checking that our new variant of the \pythonil{sqrt} function given in \cref{lst:exceptions:sqrt_raise} properly raises an \pythonilIdx{ArithmeticError} if its input is non-finite or negative.}%
632632
%
633633
\gitOutputTool{\programmingWithPythonCodeRepo}{.}{_scripts_/pytest.sh exceptions test_sqrt_raise.py}{exceptions:test_sqrt_raise:pytest}{%
634-
The output of the unit tests in \cref{lst:exceptions:test_sqrt_raise}: %
634+
The output of the \pglspl{unitTest} in \cref{lst:exceptions:test_sqrt_raise}: %
635635
The \pythonilsIdx{ArithmeticError} are correctly raised.}%
636636
%
637637

638-
Back in \cref{sec:unitTesting}, we introduced the concept of unit tests and show how the tool \pytest\ can be used to test our functions.
639-
We stated in \cref{bp:unitTestCoverage} that we should cover all the branches of the control flow inside a function with unit tests.
638+
Back in \cref{sec:unitTesting}, we introduced the concept of \pglspl{unitTest} and show how the tool \pytest\ can be used to test our functions.
639+
We stated in \cref{bp:unitTestCoverage} that we should cover all the branches of the control flow inside a function with \pglspl{unitTest}.
640640
One kind of branch that is often overlooked are \pythonilsIdx{Exception} and extension handling~\cite{LRBP2021AEHTPIOSL}.
641641

642-
If our function is supposed to \pythonilIdx{raise} a certain exception in some cases, then we should have a unit test that checks if this \pythonilsIdx{Exception} is actually raised as it should be.
643-
Now, any exception raised by a unit test will cause the test to fail.
642+
If our function is supposed to \pythonilIdx{raise} a certain exception in some cases, then we should have a \pgls{unitTest} that checks if this \pythonilsIdx{Exception} is actually raised as it should be.
643+
Now, any exception raised by a \pgls{unitTest} will cause the test to fail.
644644
This seems to contradict our goal to intentionally raise the exceptions.
645645
Luckily, \pytest\ offers us a device for this.
646646

@@ -652,10 +652,10 @@
652652
If it is raised, the text succeeds.
653653

654654
\gitPython{\programmingWithPythonCodeRepo}{exceptions/test_sqrt.py}{--args format}{exceptions:test_sqrt}{%
655-
Two unit tests checking the original variant of the \pythonil{sqrt} function from back in \cref{lst:functions:test_my_math_2} that does not raise errors.}%
655+
Two \pglspl{unitTest} checking the original variant of the \pythonil{sqrt} function from back in \cref{lst:functions:test_my_math_2} that does not raise errors.}%
656656
%
657657
\gitOutputTool{\programmingWithPythonCodeRepo}{.}{_scripts_/pytest.sh exceptions test_sqrt.py}{exceptions:test_sqrt:pytest}{%
658-
The output of the unit tests in \cref{lst:exceptions:test_sqrt}: %
658+
The output of the \pglspl{unitTest} in \cref{lst:exceptions:test_sqrt}: %
659659
No error was raised in it, so the first fails and the error message in the second test does not fit, so it fails as well.}%
660660
%
661661
In particular, we can provide the exception class as well as a \pgls{regex} via the parameter~\pythonil{match} to \pythonilIdx{raises}.
@@ -676,13 +676,13 @@
676676
Therefore, our produced error message must follow this pattern for the test to work.
677677
And, as you can find in the \pytest\ output in \cref{exec:exceptions:test_sqrt_raise:pytest}, for the values \pythonil{v in [-1.0, inf, -inf, nan]}, no error is reported.
678678
For these values, our \pythonil{sqrt} function does indeed raise\pythonIdx{raise} the expected \pythonilsIdx{Exception}, with the expected error messages.
679-
The unit test succeeds.%
679+
The \pgls{unitTest} succeeds.%
680680
\end{sloppypar}%
681681
%
682682
In \cref{lst:exceptions:test_sqrt}, we write a similar test.
683683
This time, we use basically the original version of our \pythonil{sqrt} function which does not by itself raise any exception.
684684
This function is directly implemented in the listing, in the same way as we did in \cref{lst:functions:my_math_2}, and again called \pythonil{sqrt}.
685-
We also write two unit tests into the new file \textil{test_sqrt.py}.
685+
We also write two \pglspl{unitTest} into the new file \textil{test_sqrt.py}.
686686
Both are intentionally designed to show what happens if either an expected exception is not raised~(\pythonil{test_sqrt_1}) or if its error message does not match the \pythonil{match} argument~(\pythonil{test_sqrt_2}).%
687687
%
688688
\begin{sloppypar}%
@@ -705,7 +705,7 @@
705705
So indeed, this does fulfill our testing requirement:
706706
If an \pythonilsIdx{OverflowError} is also a \pythonilIdx{ArithmeticError}, so the right type of exception was raised.
707707
However, its error message will not fit to our \pythonil{match} argument.
708-
Therefore, the unit test still fails.
708+
Therefore, the \pgls{unitTest} still fails.
709709
The output of \cref{exec:exceptions:test_sqrt:pytest} explains this clearly.%
710710
\end{sloppypar}%
711711
%
@@ -727,11 +727,11 @@
727727
%
728728
This allows us to cover both the expected and correct use of our function with tests as well as unexpected incorrect uses.
729729
We can then be confident that our code is unlikely to cause harm, neither due to bugs created by ourselves nor due to accidental misuse by other programmers due to misunderstandings (which would immediately signaled to them by \pythonilsIdx{Exception}).
730-
Notice that good unit testing goes hand in hand with good documentation in \pglspl{docstring}, because good \pglspl{docstring} reduce the chance of such misunderstandings.%
730+
Notice that good \pglspl{unitTest} go hand in hand with good documentation in \pglspl{docstring}, because good \pglspl{docstring} reduce the chance of such misunderstandings.%
731731
%
732732
\bestPractice{testAll}{%
733733
It is important to cover both the reasonable expected use of our functions as well as unexpected use with incorrect arguments with test cases. %
734-
The latter case should raise\pythonIdx{raise} \pythonilsIdx{Exception}, which we should verify with unit tests.%
734+
The latter case should raise\pythonIdx{raise} \pythonilsIdx{Exception}, which we should verify with \pglspl{unitTest}.%
735735
}%
736736
%
737737
\FloatBarrier%
@@ -865,7 +865,7 @@
865865

866866
Error handling in \python\ therefore allows us to develop software that is both robust and that clearly indicates if something goes wrong.
867867
Of course, for software to be called \emph{robust}, it has to be tested.
868-
Luckily, \pytest\ offers us also unit testing capabilities that check whether \pythonilsIdx{Exceptions} are raised where expected.
868+
Luckily, \pytest\ offers us also \pgls{unitTest} capabilities that check whether \pythonilsIdx{Exceptions} are raised where expected.
869869
This completes our discussion of the error-related control flow.%
870870
\endhsection%
871871
%

0 commit comments

Comments
 (0)