|
135 | 135 | The computation of the greatest common divisor, also known as~\pythonil{gcd}.
|
136 | 136 |
|
137 | 137 | 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{\%}. |
139 | 139 | This means that $g$~divides both $a$ and $b$ without remainder.
|
140 | 140 | If $a=b$, then obviously $\pythonil{gcd}(a,b)=a=b$ as well.
|
141 | 141 | Otherwise, we know that $a=ig$ for some~$i\in\naturalNumbersO$ and $b=jg$ for some~$j\in\naturalNumbersO$.
|
|
192 | 192 | \FloatBarrier%
|
193 | 193 | \endhsection%
|
194 | 194 | %
|
| 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 | +% |
195 | 263 | \endhsection%
|
196 | 264 | %
|
0 commit comments