Skip to content

Commit e02bb13

Browse files
committed
modules and import
1 parent 8d2687f commit e02bb13

File tree

3 files changed

+104
-12
lines changed

3 files changed

+104
-12
lines changed

bibliography/bibliography.bib

+34-11
Original file line numberDiff line numberDiff line change
@@ -1655,52 +1655,52 @@ @proceedings{PROC2023GECCO
16551655

16561656
@inbook{PSF2024BIT,
16571657
title = {Built-in Types},
1658-
crossref = {PSF2024P3D},
1658+
xdata = {PSF2024TPSL},
16591659
url = {https://docs.python.org/3/library/stdtypes.html},
16601660
urldate = {2024-08-22},
16611661
}
16621662

16631663
@inbook{PSF2024CAABCFC,
16641664
title = {\pythonil{collections.abc} -- Abstract Base Classes for Containers},
1665-
crossref = {PSF2024P3D},
1665+
xdata = {PSF2024TPSL},
16661666
url = {https://docs.python.org/3/library/collections.abc.html},
16671667
urldate = {2024-08-22},
16681668
}
16691669

16701670
@inbook{PSF2024D,
16711671
title = {Dictionaries},
16721672
chapter = {3.2.7.1},
1673-
crossref = {PSF2024P3D},
1673+
xdata = {PSF2024TPLR},
16741674
url = {https://docs.python.org/3/reference/datamodel.html#dictionaries},
16751675
urldate = {2024-08-27},
16761676
}
16771677

16781678
@inbook{PSF2024DM,
16791679
title = {Data Model},
16801680
chapter = {3},
1681-
crossref = {PSF2024P3D},
1681+
xdata = {PSF2024TPLR},
16821682
url = {https://docs.python.org/3/reference/datamodel.html},
16831683
urldate = {2024-08-22},
16841684
}
16851685

16861686
@inbook{PSF2024FSL,
16871687
title = {Formatted String Literals},
16881688
chapter = {7.1.1},
1689-
crossref = {PSF2024P3D},
1689+
xdata = {PSF2024TPT},
16901690
url = {https://docs.python.org/3/tutorial/inputoutput.html#formatted-string-literals},
16911691
urldate = {2024-07-25},
16921692
}
16931693

16941694
@inbook{PSF2024IPM,
16951695
title = {Installing \python\ Modules},
16961696
crossref = {PSF2024P3D},
1697-
url = {https://docs.python.org/3/installing/index.html},
1697+
url = {https://docs.python.org/3/installing},
16981698
urldate = {2024-08-17},
16991699
}
17001700

17011701
@inbook{PSF2024NTIFC,
17021702
title = {Numeric Types -- \pythonilIdx{int}, \pythonilIdx{float}, \pythonilIdx{complex}},
1703-
crossref = {PSF2024P3D},
1703+
xdata = {PSF2024TPSL},
17041704
url = {https://docs.python.org/3/library/stdtypes.html#typesnumeric},
17051705
urldate = {2024-07-05},
17061706
}
@@ -1723,7 +1723,7 @@ @inbook{PSF2024PSAU
17231723

17241724
@inbook{PSF2024S,
17251725
title = {Sequences},
1726-
crossref = {PSF2024P3D},
1726+
xdata = {PSF2024TPLR},
17271727
chapter = {3.2.5},
17281728
url = {https://docs.python.org/3/reference/datamodel.html#sequences},
17291729
urldate = {2024-08-24},
@@ -1732,18 +1732,36 @@ @inbook{PSF2024S
17321732
@inbook{PSF2024ST,
17331733
title = {Set Types},
17341734
chapter = {3.2.6},
1735-
crossref = {PSF2024P3D},
1735+
xdata = {PSF2024TPLR},
17361736
url = {https://docs.python.org/3/reference/datamodel.html#set-types},
17371737
urldate = {2024-08-27},
17381738
}
17391739

1740+
@inbook{PSF2024TIS,
1741+
title = {The Import System},
1742+
chapter = {5},
1743+
xdata = {PSF2024TPLR},
1744+
url = {https://docs.python.org/3/reference/import.html},
1745+
urldate = {2024-10-01}
1746+
}
1747+
17401748
@inbook{PSF2024STSF,
17411749
title = {Set Types -- set, frozenset},
1742-
crossref = {PSF2024P3D},
1750+
xdata = {PSF2024TPSL},
17431751
url = {https://docs.python.org/3/library/stdtypes.html#set},
17441752
urldate = {2024-08-27},
17451753
}
17461754

1755+
@xdata{PSF2024TPLR,
1756+
volume = {The \python\ Language Reference},
1757+
crossref = {PSF2024P3D}
1758+
}
1759+
1760+
@xdata{PSF2024TPSL,
1761+
volume = {The \python\ Standard Library},
1762+
crossref = {PSF2024P3D}
1763+
}
1764+
17471765
@book{PSF2024TPPIP,
17481766
title = {The \python\ Package Index~(\pypi)},
17491767
url = {https://pypi.org/},
@@ -1753,9 +1771,14 @@ @book{PSF2024TPPIP
17531771
address = pa_python_software_foundation,
17541772
}
17551773

1774+
@xdata{PSF2024TPT,
1775+
volume = {The \python\ Tutorial},
1776+
crossref = {PSF2024P3D}
1777+
}
1778+
17561779
@inbook{PSF2024TSTS,
17571780
title = {Text Sequence Type -- \pythonilIdx{str}},
1758-
crossref = {PSF2024P3D},
1781+
xdata = {PSF2024TPSL},
17591782
url = {https://docs.python.org/3/library/stdtypes.html#textseq},
17601783
urldate = {2024-07-25},
17611784
}

styles/listing.sty

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ literate=%
6565
{∖}{{$\setminus$}}1 {∪}{{$\cup$}}1 {∩}{{$\cap$}}1%
6666
{≈}{{$\approx$}}1 {∈}{{$\in$}}1 {∉}{{$\notin$}}1%
6767
{√}{{\raisebox{0.55ex}{$\sqrt{\relax}$}}}1%
68+
{²}{{\textsuperscript{2}}}1{³}{{\textsuperscript{3}}}1%
6869
}%
6970
%
7071
\lstdefinestyle{python_style}{%

text/main/controlFlow/functions/functions.tex

+69-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
The computation of the greatest common divisor, also known as~\pythonil{gcd}.
136136

137137
This can be done using the Euclidean algorithm~\cite{EHF2008ENT,B1999FAOTBEA,TKY2016BEOEAOTCEG}, going back to \citeauthor{EHF2008ENT} who flourished about 300~BCE.
138-
The greatest commond divisor of two numbers positive~$a\in\naturalNumbersO$ and~$b\in\naturalNumbersO$ is the greatest number~$g\in\naturalNumbersO=\pythonil{gcd}(a,b)$ such that~$a\bmod g=0$ and~$b \bmod g=0$, where~$\bmod$ is the \pgls{modulodiv} operator equivalent to \python's~\pythonilIdx{\%}.
138+
The greatest common divisor of two numbers positive~$a\in\naturalNumbersO$ and~$b\in\naturalNumbersO$ is the greatest number~$g\in\naturalNumbersO=\pythonil{gcd}(a,b)$ such that~$a\bmod g=0$ and~$b \bmod g=0$, where~$\bmod$ is the \pgls{modulodiv} operator equivalent to \python's~\pythonilIdx{\%}.
139139
This means that $g$~divides both $a$ and $b$ without remainder.
140140
If $a=b$, then obviously $\pythonil{gcd}(a,b)=a=b$ as well.
141141
Otherwise, we know that $a=ig$ for some~$i\in\naturalNumbersO$ and $b=jg$ for some~$j\in\naturalNumbersO$.
@@ -192,5 +192,73 @@
192192
\FloatBarrier%
193193
\endhsection%
194194
%
195+
\hsection{Functions in Modules}%
196+
%
197+
\gitPython{\programmingWithPythonCodeRepo}{05_functions/my_math.py}{--args format}{functions:my_math}{%
198+
The module \pythonil{my_math}, which provides two mathematics functions, namely \pythonil{sqrt}, implementing the algorithm of Heron to compute the square root from \cref{lst:loops:while_loop_sqrt}, and \pythonil{factorial}, copied from \cref{lst:functions:def_factorial}.}%
199+
%
200+
You may not have noticed it, but we just made a very big step in our programming skills.
201+
We moved from simple programs which only consist of one big block of code to modular programs.
202+
We can now reuse code.
203+
And we can distribute code over multiple files.
204+
This clearly is a concern for any application larger than a simple script:
205+
How can we avoid writing our applications as a single, huge, and unstructured file which would be impossible to maintain in the long run?
206+
How can we divide our application into smaller units that we can test, improve, and maintain separately and maybe use and reuse in different contexts?
207+
A big part of the answer to this question are \emph{modules} and \emph{packages}~\cite{PSF2024TIS}.
208+
209+
For all intents and purposes within this book, a \emph{module}\pythonIdx{module} is a \python\ file and a \emph{package}\pythonIdx{package} is a directory wherein the file is located.
210+
As described in~\cite{PSF2024TIS}, modules do not necessarily need to be files and packages can probably be created otherwise as well, but let us keep it simple here.
211+
212+
Indeed, we have already worked with modules, most prominently the~\pythonilIdx{math} module.
213+
This module is basically a collection of mathematical functions.
214+
Since we have implemented several mathematical functions by ourselves, let us put some of them in a module as well.
215+
216+
In \cref{lst:functions:my_math} we do just that.
217+
We create the \python\ file \textil{my_math.py} and place two functions into it:
218+
The function \pythonil{factorial} from \cref{lst:functions:def_factorial} and a new function called \pythonil{sqrt}.
219+
The \pythonil{sqrt} function basically encapsulates our code from back in \cref{lst:loops:while_loop_sqrt}, where we implemented the Heron's Method to compute the square root, as a function.
220+
Now, \pythonil{number}, the input of this algorithm, comes in as a parameter.%
221+
%
222+
\bestPractice{packageAndModuleNames}{Package and module names should be short and lowercase. Underscores can be used to improve readability.~\cite{PEP8}}%
223+
%
224+
Our new module \textil{my_math} does not look very special or different from what we did so far.
225+
The one difference that we notice, however, is that it \inQuotes{does nothing}.
226+
In the file, we define two functions, but we do not actively call them, we do not use them for anything.
227+
This is the purpose of this module:
228+
It just provides the functions.
229+
We will use them elsewhere.
230+
231+
\gitPythonAndOutput{\programmingWithPythonCodeRepo}{05_functions}{use_my_math.py}{--args format}{functions:use_my_math}{%
232+
A program using the functions \pythonil{sqrt} and \pythonil{factorial} from the module \pythonil{my_math} given in \cref{lst:functions:my_math}.}%%
233+
%
234+
\begin{sloppypar}%
235+
\Cref{lst:functions:use_my_math} is where we use them:
236+
We write a program, i.e., another \python\ file, named \textil{use_my_math.py}.
237+
In this file, we want to use our two functions \pythonil{factorial} and \pythonil{sqrt} from the module \pythonil{my_math}.
238+
For this purpose, we have to tell the \python\ interpreter where it can find these two functions.
239+
We do this by writing \pythonil{from my_math import factorial, sqrt}\pythonIdx{from}\pythonIdx{import}\pythonIdx{module}.
240+
The meaning of the line is quite obvious:
241+
There is a module \pythonil{my_math} from which we want to import, i.e., make available, two functions, namely \pythonil{factorial} and \pythonil{sqrt}.%
242+
\end{sloppypar}%
243+
%
244+
Now, the \python\ interpreter knows a lot of modules.
245+
Several modules ship with any \python\ installation, like \pythonilIdx{math}.
246+
Others are installed via a package manager like \pgls{pip}~\cite{PSF2024IPM} (we will eventually discuss this later).
247+
The \pythonil{my_math} module is found because it is in the same directory as the program \textil{use_my_math}.
248+
249+
If we had placed the \textil{my_math.py} file into a sub-directory named \textil{math_pack} instead, then we would import our functions from \textil{math_pack.my_math} instead, where \textil{math_pack} would be called a~\emph{package}.
250+
Of course, we could also create another level of directories, say we could have directory \textil{utils}, containing directory \textil{math_pack}, containing our file \pythonil{my_math.py}.
251+
In this case, we would import our functions like \pythonil{from utils.math_pack.my_math import}\dots.
252+
The names of package and modul are separated by a~\pythonilIdx{.} when importing from them.
253+
This allows us to nicely and hierarchically structure our projects into modules and packages for different purposes.
254+
255+
In \cref{lst:functions:use_my_math} we can use both \pythonil{sqrt} and \pythonil{factorial} exactly as if we had defined them in this program.
256+
We first print a few values for \pythonil{sqrt} and \pythonil{factorial} and also show that we can compute the result of the square root of a factorial.
257+
We also just copy the code from \cref{lst:loops:for_loop_pi_liu_hui}, where we use LIU Hui's method to approximate~\numberPi\ -- but this time, we use our own implementation of the square root function instead of the one from the \pythonil{math} module.
258+
Interestingly, the sixth and last approximation step in \cref{exec:functions:use_my_math} shows exactly the same result as in \cref{exec:loops:for_loop_pi_liu_hui}.%
259+
%
260+
\FloatBarrier%
261+
\endhsection%
262+
%
195263
\endhsection%
196264
%

0 commit comments

Comments
 (0)