Skip to content

Commit 73ce171

Browse files
committed
more steps into Fraction
1 parent d7aa945 commit 73ce171

File tree

8 files changed

+436
-40
lines changed

8 files changed

+436
-40
lines changed

bibliography/bibliography.bib

+229-16
Large diffs are not rendered by default.

notation/acronyms.sty

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
%%% The acronyms.
33
%%%
44
%
5+
\newacronym[description={an Application Programming Interface is a set of rules or protocols that enables one software application or component to use or communicate with another~\cite{G2024WIAA}}]{API}{API}{Application Programming Interface}%
56
\newacronym[description={Artificial Intelligence, see, e.g.,~\cite{RN2022AIAMA}}]{AI}{AI}{Artificial Intelligence}%
67
\newacronym[description={Comma-Separated Values, see, e.g.,~\cite{PSF2024CCFRAW,S2005CFAMTFCSVCF} and~\pgls{csv}}]{CSV}{CSV}{Comma-Separated Values}%
78
\newacronym[description={Data Science, see, e.g.,~\cite{G2019DSFSFPWP}}]{DS}{DS}{Data Science}%

notation/math.sty

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ It holds that~$\integerNumbers\subset\realNumbers$%
2121
\newSymbol{realNumbersP}{\ensuremath{\mathSpace{R}^+}}{R+}{%
2222
the set of the positive real numbers, i.e., $\mathSpace{R}^+=\{x\in\realNumbers:x>0\}$}%
2323
%
24+
\newSymbol{rationalNumbers}{\mathSpace{Q}}{Q}{%
25+
the set of the rational numbers, i.e., the set of all numbers that can be the result of~$\frac{a}{b}$ with~$a,b\in\integerNumbers$ and~$b\neq0$. %
26+
$a$~is called the \pgls{numerator} and $b$~is called the \pgls{denominator}. %
27+
It holds that~$\integerNumbers\subset\rationalNumbers$ and $\rationalNumbers\subset\realNumbers$%
28+
}%
29+
%
2430
\protected\gdef\intRange#1#2{\ensuremath{#1\gls{intSetDots}#2}}%
2531
\newglossaryentry{intSetDots}{%
2632
type={symbols},

notation/software.sty

+11-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,17 @@ Learn more at \url{https://simpy.readthedocs.io}.}
220220
}%
221221
\protected\gdef\simpy{\pgls{simpy}}%
222222
%
223-
223+
%
224+
\newglossaryentry{sphinx}{%
225+
text={\softwareStyle{Sphinx}},%
226+
name={Sphinx},%
227+
sort={Sphinx},%
228+
description={\sphinx\ is a tool for generating software documentation~\cite{TTSFABFSKSD2024SCIABDWE}. %
229+
It supports \python\ can use both \pglspl{docstring} and \pglspl{typeHint} to generate beautiful documents. %
230+
Learn more at \url{https://www.sphinx-doc.org}.}
231+
}%
232+
\protected\gdef\sphinx{\pgls{sphinx}}%
233+
%
224234
%
225235
\newglossaryentry{tensorflow}{%
226236
text={\softwareStyle{TensorFlow}},%

notation/terms.sty

+24
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ is another programming language, which is very successful in system programming
4444
}%
4545
%
4646
%
47+
\newglossaryentry{denominator}{%
48+
name={denominator},%
49+
description={%
50+
The number~$b$ of a fraction~$\frac{a}{b}\in\rationalNumbers$ is called the \emph{denominator}.}%
51+
}%
52+
%
53+
%
4754
\newglossaryentry{doctest}{%
4855
name={doctest},%
4956
description={%
@@ -122,6 +129,13 @@ For this course, we recommend using \pycharm.%
122129
}%
123130
%
124131
%
132+
\newglossaryentry{numerator}{%
133+
name={numerator},%
134+
description={%
135+
The number~$a$ of a fraction~$\frac{a}{b}\in\rationalNumbers$ is called the \emph{numerator}.}%
136+
}%
137+
%
138+
%
125139
\newglossaryentry{strinterpolation}{%
126140
name={(string) interpolation},%
127141
sort={string interpolation},
@@ -191,6 +205,16 @@ See \cref{sec:howFloatingPointNumbersWork}.%
191205
}%
192206
%
193207
%
208+
\newglossaryentry{signature}{%
209+
name={signature},%
210+
description={%
211+
\pythonIdx{function!signature}%
212+
The signature of a function refers to the parameters and their types, the return type, and the exceptions that the function can raise~\cite{M2023SF}. %
213+
In \python, the function~\pythonilIdx{signature} of the module~\pythonilIdx{inspect} provides some information about the signature of a function~\cite{PEP362}.%
214+
}%
215+
}%
216+
%
217+
%
194218
\newglossaryentry{signBit}{%
195219
name={sign bit},%
196220
description={%

text/main/classes/basics/basics.tex

+58-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,55 @@
11
\hsection{Basics of Classes}%
22
%
3-
Classes are, basically, a semantic unit of data and code.
43
We learned about simple datatypes in \cref{sec:simplyDataTypesAndOperations} and about collections in \cref{sec:collections}.
54
However, in many situations, we deal with data that cannot satisfyingly represented by either of them alone.
6-
Moreover, often, datatypes and the operations on them form a semantic unit.
7-
For this purpose, \emph{classes} exist in \python\pythonIdx{class}:%
5+
Often, datatypes and the operations on them form a semantic unit.
6+
7+
Imagine, for example, you would like to implement mathematical operations for complex numbers.\footnote{%
8+
\python\ already offers the datatype \pythonilIdx{complex}, but for the sake of the example, assume it does not.}
9+
Of course, you could represent complex numbers as \pythonil{tuple[float, float]}, but this comes with several drawbacks.
10+
On one hand, not \emph{every} tuple of two \pythonils{float} is to be understood as a complex number.
11+
So just from the \pgls{signature} of your functions, i.e., just based on its parameters and return types, it is not immediately clear that your functions are for complex numbers.
12+
All we can directly see is that they are for tuples of two \pythonils{float}.
13+
On the other hand, the two parts of a complex numbers, the real part and the imaginary part, have two distinct and different meanings.
14+
It would not immediately be clear whether the first number of the tuple is the real or the imaginary part.
15+
Indeed, we could also represent complex numbers in polar form, in which case the two tuple elements would have yet different meanings.
16+
Also, the standard textual representation of tuples of two \pythonils{float} would be something like~\pythonil{"(3.0, 4.0)"}, whereas we would probably prefer something like~\pythonil{"3+4i"}.
17+
18+
The first important use-cases of \pythoniles{class} in \python\ is that they offer us a way to define a data structure together with the operations for it as one semantic unit.
19+
This allows us to define a \pythonil{class} for complex numbers which has attributes with the name \pythonil{real_part} and \pythonil{imaginary_part}.
20+
We can define operators that work with instances of this \pythonil{class}, making it immediately clear how and when they are to be used-
21+
And this \pythonil{class} can then have default textual representations of our liking.
22+
23+
A second situation where ability to define functions and we have learned so far hits a limit arises with \pglspl{API}.
24+
Let us be ambitious and imagine that you wanted to create a versatile system that can produce documents.
25+
On the output side, you want to support different formats, say LibreOffice~\cite{DF2024LTDF,GL2012LTSOOSSCBAFACSOL}, Microsoft~Word~\cite{MS2024MW,DR2019STFAWAUMW}, and Adobe~PDF~\cite{A2024WDPM,A2008P3DMPDFP1P1}.
26+
On the input side, you would like to provide the user with a uniform way to create documents, to add text paragraphs, to insert graphics, to set the font of texts, and so on.
27+
This input side \pgls{API} should be the same for all output formats.
28+
It would not just consist of a single function, but several groups of functions.
29+
There could even be nested hierarchies of operations that you would like to support, e.g., the ability to divide a text into chapters which can be divided into paragraphs which can be divided into runs of text with different fonts.
30+
Obviously, these operations will be implemented differently for the different output formats.
31+
We could try to solve this by making different modules with functions of the same \pglspl{signature} for the different output formats.
32+
But this would be a huge hassle, in particular since there would be no way to define a central blueprint of \inQuotes{how the \pgls{API} looks like.}
33+
It can easily lead to inconsistencies during the software life cycle.
34+
If we slightly change the \pgls{signature} of one function, we need to implement this in all of the modules.
35+
There also is no way that a tool like \ruff\ could tell is if some module is no longer synchronized due to the lack of a central blueprint.
36+
37+
Classes offer us the necessary abstraction:
38+
We could specify a base class \pythonil{Document} for document objects that provides methods for the necessary operations, from adding text to aligning figures.
39+
These operations could just \pythonilIdx{raise} a \pythonilIdx{NotImplementedError}.
40+
Then, for each output format, we could derive a new subclass from this base class with the actual implementation of the methods.
41+
The code on the user side could treat all these different document types the same, because all of them would be instances of \pythonil{Document} with the same operations.
42+
The implementation-specific stuff would all be invisible to the user, exactly as it should be.
43+
So the second important use case for classes are that they offer us a very nice abstraction for defining and implementing \pglspl{API}.
44+
45+
Classes therefore can solve two important problems where the basic datatypes and plain functions we learned about are not sufficient:
46+
First, they allow us to semantically and clearly group data and operations together.
47+
Second, they offer us a simple way to group several operators under one \pgls{API}, which then -- transparently to the user -- can be implemented in different ways.
48+
In this chapter, we discuss \pythoniles{class} in \python.
49+
Syntactly, \pythoniles{classes} follow the general blueprint below:%
850
%
951
\begin{pythonSyntax}
10-
class:
52+
class MyClass: # or `class MyClass(MyBaseClass)`
1153
"""Docstring of the class."""
1254

1355
def __init__(self) -> None:
@@ -22,6 +64,9 @@
2264
# compute something using the attributes
2365
\end{pythonSyntax}
2466
%
67+
\bestPractice{className}{\sloppy%
68+
Class names should follow the CapWords convention (often also called camel case), i.e., look like \pythonil{MyClass} or \pythonil{UniversityDepartment} (not \pythonil{my_class} or \pythonil{university_department})~\cite{PEP8}.}%
69+
%
2570
\hsection{A Simple Immutable Class for Points in the Two-Dimensional Euclidean Plane}%
2671
\label{sec:immutableClassPoints2D}%
2772
%
@@ -95,15 +140,18 @@
95140
}
96141
These lines create the attributes \pythonil{self.x} and \pythonil{self.y} of the object which was passed in via the parameter~\pythonil{self}.
97142
Additionally, the \pgls{typeHint} \pythonilIdx{Final} from the \pythonilIdx{typing} module annotates a variable as immutable~\cite{PEP591}.
98-
In other words, we do not allow the coordinates of our \pythonils{Point} to be change after creation.%
143+
In other words, we do not allow the coordinates of our \pythonils{Point} to change after object creation.%
99144
%
100145
\bestPractice{attributeTypeHint}{%
101-
Every attribute of an object must be annotated with a \pgls{typeHint} and a documentation comment when created in the initializer~\pythonilIdx{\_\_init\_\_}\pythonIdx{dunder!\_\_init\_\_}. %
102-
\pglspl{typeHint} work as with normal variables, but the documentation is slightly different: %
103-
In the line \emph{above} the attribute initialization, a \emph{comment} starting with \pythonilIdx{\#: } must be written which explains the meaning of the attribute.%
146+
Every attribute of an object must be annotated with a \pgls{typeHint} and a documentation comment when created in the initializer~\pythonilIdx{\_\_init\_\_}\pythonIdx{dunder!\_\_init\_\_}~\cite{LM2024WTMD}. %
147+
\pglspl{typeHint} work as with normal variables.}%
148+
%
149+
\bestPractice{attributeDocstring}{%
150+
An attribute is documented in the line \emph{above} the attribute initialization by writing a \emph{comment} starting with \pythonilIdx{\#: }, which explains the meaning of the attribute~\cite{SD2024DCAD}. %
151+
(Sometimes, the documentation is given as string directly below the attribute definition~\cite{PEP287}, but we stick to the former method, because it has proper tool support, e.g., by~\sphinx.)%
104152
}%
105153
%
106-
We can now do something like \pythonil{p = Point(1, 2)} and it will create the object~\pythonil{p} which is an instance of the \pythonilIdx{class} \pythonil{Point}.
154+
After properly defining our initializer, we can now do something like \pythonil{p = Point(1, 2)} and it will create the object~\pythonil{p} which is an instance of the \pythonilIdx{class} \pythonil{Point}.
107155
This will allocate the memory for~\pythonil{p} and automatically invoke \pythonil{\_\_init\_\_(p, 1, 2)}.
108156
As a result, \pythonil{p.x} will have the value~\pythonil{1} and \pythonil{p.y} will have value~\pythonil{2}.
109157
Notice that we can immediately see from the knowledge that \pythonil{p} is an instance of \pythonil{Point} that \pythonil{p.x} and \pythonil{p.y} are its x\nobreakdashes-\ and y\nobreakdashes-coordinate, respectively.
@@ -122,7 +170,7 @@
122170
If you compute \pythonil{Point(1, 1).distance(Point(4, 4))}, then the expected result is something like~4.243.%
123171
%
124172
\bestPractice{methodDocstring}{%
125-
All methods of \pythoniles{class} must be annotated with \pglspl{docstring}.%
173+
All methods of \pythoniles{class} must be annotated with \pglspl{docstring} and \pglspl{typeHint}.%
126174
}%
127175
%
128176
We could now go on and add more methods that do reasonable computations with instances of~\pythonil{Point}.

0 commit comments

Comments
 (0)