From d23c2f577e214e02acd65913e25d17a6ef8f5b16 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Fri, 14 Oct 2016 12:16:43 +0200 Subject: [PATCH] [translation] scripts and functions done... maybe --- programming/lecture/programming-chapter.tex | 4 + programming/lecture/programming.tex | 220 +++++++++++--------- 2 files changed, 130 insertions(+), 94 deletions(-) diff --git a/programming/lecture/programming-chapter.tex b/programming/lecture/programming-chapter.tex index 8d41a07..6b04454 100644 --- a/programming/lecture/programming-chapter.tex +++ b/programming/lecture/programming-chapter.tex @@ -29,6 +29,10 @@ \item Doppelte for-Schleife \item File output and input (load, save, fprintf, scanf) (extra chapter?) \item help() und doc() +\item A box about sampling of contiunous data. +\item A box about foo and bar? +\item function arguments, order does matter, names do as well. +\item function return values. order does not matter, names do \end{itemize} \end{document} diff --git a/programming/lecture/programming.tex b/programming/lecture/programming.tex index dd248f7..50adf7d 100644 --- a/programming/lecture/programming.tex +++ b/programming/lecture/programming.tex @@ -15,7 +15,7 @@ variable is read from the memory, this binary pattern is interpreted according to the data type. The example shown in figure~\ref{variablefig} shows that the very same bit pattern is either interpreted as a 8-bit integer type (numeric value 38) or as a -ampersand (&) character. In \matlab{} data types are of only minor +ampersand (\&) character. In \matlab{} data types are of only minor importance but there are occasions where it becomes important to know the type of a variable and we will come back to them later on. @@ -261,7 +261,7 @@ c = The length of a vector, that is the number of elements, can be requested using the \code{length()} or \code{numel()} functions. \code{size()} provides the same information in a slightly, -yet more powerful way (listing~\ref{vectorsizelisting}). The above +yet more powerful way (listing~\ref{vectorsizeslisting}). The above used vector \varcode{a} has the following size: \begin{lstlisting}[label=vectorsizeslisting, caption={Size of a vector.}] @@ -937,9 +937,10 @@ The basic concept is that applying a Boolean operation on a vector results in a \code{logical} vector of the same size (see listing~\ref{booleanexpressions}. This logical vector is then used to select only those values for which the logical vector is true. Line 14 -in listing~\ref{logicalindexing} can be read: ``Give me all those +in listing~\ref{logicalindexing1} can be read: ``Select all those elements of \varcode{x} where the Boolean expression \varcode{x < 0} -evaluates to true''. +evaluates to true and store the result in the variable +\emph{x\_smaller\_zero}''. \begin{lstlisting}[caption={Logical indexing.}, label=logicalindexing1] >> x = randn(1, 6) % a vector with 6 random numbers @@ -1193,7 +1194,7 @@ that defines against which the \emph{switch expression} is tested. It is important to note that the case expression always checks for equality! Optional the case expressions may be followed by the keyword \code{otherwise} which catches all cases that were not explicitly -stated above (listing~\ref{switchlistin}). +stated above (listing~\ref{switchlisting}). \begin{lstlisting}[label=switchlisting, caption={Structure of a \varcode{switch} statement.}] @@ -1309,20 +1310,20 @@ programs increases the re-usability. So far we have used \emph{scripts} to store the solutions of the exercises. Any variable that was created appeared in the \codeterm{workspace} and existed even after the program was finished. This is very convenient but also bears -some risks. Consider the case that \file{script_a.m} creates a certain -variable and assigns a value to it for later use. Now it calls a -second program (\file{script_b.m}) that, by accident, uses the same +some risks. Consider the case that \file{script\_a.m} creates a +certain variable and assigns a value to it for later use. Now it calls +a second program (\file{script\_b.m}) that, by accident, uses the same variable name and assigns a different value to it. When -\file{script_b.m} is done, the control returns to \file{script_a.m} -and if it now want to read the previously stored variable, it will +\file{script\_b.m} is done, the control returns to \file{script\_a.m} +and if it now wants to read the previously stored variable, it will contain a different value than expected. Bugs like this are hard to -track down since each of the programs alone is perfectly fine and -works as intended. A solution for this problem are the +find since each of the programs alone is perfectly fine and works as +intended. A solution for this problem are the \codeterm[Function]{functions}. \subsection{Functions} -Functions in \matlab{} are similar to a mathematical functions +Functions in \matlab{} are similar to mathematical functions \[ y = f(x) \] Here, the mathematical function has the name $f$ and it has one \codeterm{argument} $x$ that is transformed into the function's output value $y$. In \matlab{} the syntax of a function @@ -1361,10 +1362,10 @@ using functions instead of scripts we gain several advantages: \end{itemize} The following listing (\ref{badsinewavelisting}) shows a function that -calculates and displays a bunch of sines with different amplitudes. +calculates and displays a bunch of sine waves with different amplitudes. -\begin{lstlisting}[caption={Bad example of a function that displays a series of sines.},label=badsinewavelisting] +\begin{lstlisting}[caption={Bad example of a function that displays a series of sine waves.},label=badsinewavelisting] function meineFirstFunction() % function head t = (0:0.01:2); frequency = 1.0; @@ -1407,36 +1408,36 @@ defined: As indicated above the \code{myFirstFunction} does three things at once, it seems natural, that the task should be split up into three -parts. (i) Calculation of the individual sine-wave defined by the -frequency and the amplitude (ii) graphical display of the data and +parts. (i) Calculation of the individual sine waves defined by the +frequency and the amplitudes (ii) graphical display of the data and (iii) coordination of calculation and display. -\paragraph{I. Calculation of a single sine-wave} +\paragraph{I. Calculation of a single sine wave} -Before we start coding it is best, to again think about the task and +Before we start coding it is best to again think about the task and define (i) how to name the function, (ii) which information it needs (arguments), and (iii) what it should return to the caller. \begin{enumerate} -\item \codeterm[Funktion!Name]{Name}: der Name sollte beschreiben, was - die Funktion tut. In diesem Fall berechnet sie einen Sinus. Ein - geeigneter, kurzer Name w\"are also \code{sinewave()}. -\item \codeterm[Funktion!Argumente]{Argumente}: die zu brechnende - Sinusschwingung sei durch ihre Frequenz und die Amplitude - bestimmt. Des Weiteren soll noch festgelegt werden, wie lang der - Sinus sein soll und mit welcher zeitlichen Aufl\"osung gerechnet - werden soll. Es werden also vier Argumente ben\"otigt, sie k\"onnten - hei{\ss}en: \varcode{amplitude}, \varcode{frequency}, - \varcode{t\_max}, \varcode{t\_step}. -\item \codeterm[Funktion!R{\"u}ckgabewerte]{R\"uckgabewerte}: Um den - Sinus korrekt darstellen zu k\"onnen brauchen wir die Zeitachse und - die entsprechenden Werte. Es werden also zwei Variablen - zur\"uckgegeben: \varcode{time}, \varcode{sine} +\item \codeterm[Function!Name]{Name}: the name should be descriptive + of the function's purpose, i.e. the calculation of a sine wave. A + appropriate name might be \code{sinewave()}. +\item \codeterm[Function!Arguments]{Arguments}: What information does + the function need to do the calculation? There are obviously the + frequency as well as the amplitude. Further we may want to be able + to define the duration of the sine wave and the temporal + resolution. We thus need four arguments which should also named to + describe their content: \code{amplitude, frequency, t\_max,} and + \code{t\_step} might be good names. +\item \codeterm[Function!Return values]{Return values}: For a correct + display of the data we need two vectors. The time, and the sine wave + itself. We just need two return values: \varcode{time}, \varcode{sine} \end{enumerate} -Mit dieser Information ist es nun gut m\"oglich die Funktion zu -implementieren (Listing \ref{sinefunctionlisting}). -\begin{lstlisting}[caption={Funktion zur Berechnung eines Sinus.}, label=sinefunctionlisting] +Having defined this we can start coding +(listing~\ref{sinefunctionlisting}). + +\begin{lstlisting}[caption={Function that calculates a sine wave.}, label=sinefunctionlisting] function [time, sine] = sinewave(frequency, amplitude, t_max, t_step) % Calculate a sinewave of a given frequency, amplitude, % duration and temporal resolution. @@ -1452,23 +1453,36 @@ function [time, sine] = sinewave(frequency, amplitude, t_max, t_step) % time: vector of the time axis % sine: vector of the calculated sinewave time = (0:t_step:t_max); - sine = sin(frequency .* time .* 2 * pi) .* amplitude; + sine = sin(frequency .* time .* 2 .* pi) .* amplitude; end \end{lstlisting} -\paragraph{II. Plotten einer einzelnen Schwingung} -Das Plotten der berechneten Sinuschwingung kann auch von einer -Funktion \"ubernommen werden. Diese Funktion hat keine andere Aufgabe, -als die Daten zu plotten. Ihr Name sollte sich an dieser Aufgabe -orientieren (z.B. \code{plotFunction()}). Um einen einzelnen Sinus -zu plotten werden im Wesentlichen die x-Werte und die zugeh\"origen -y-Werte ben\"otigt. Da mehrere Sinus geplottet werden sollen ist es -auch sinnvoll eine Zeichenkette f\"ur die Legende an die Funktion zu -\"ubergeben. Da diese Funktion keine Berechnung durchf\"uhrt wird kein -R\"uckgabewert ben\"otigt (Listing \ref{sineplotfunctionlisting}). - -\begin{lstlisting}[caption={Funktion zur graphischen Darstellung der Daten.}, label=sineplotfunctionlisting] +\paragraph{II. Plotting a single sine wave} +The display of the sine waves can also be delegated to a function. We +can now decide whether we want the function to plot all sine waves at +once, or if we want design a function that plots a single sine wave +and that we then call repeatedly for each frequency/amplitude +combination. The most flexible approach is the latter and we will +thus implement it this way. We might come up with the following +specification of the function: + +\begin{enumerate} +\item It should plot a single sine wave. But it is not limited to sine + waves. It's name is thus: \code{plotFunction()}. +\item What information does it need to solve the task? The + to-be-plotted data as there is the values \code{y\_data} and the + corresponding \code{x\_data}. As we want to plot series of sine + waves we might want to have a \code{name} for each function to be + displayed in the figure legend. +\item Are there any return values? No, this function is just made for + plotting, we do not need to return anything. +\end{enumerate} + +With this specification we can start to implement the function +(listing~\ref{sineplotfunctionlisting}). + +\begin{lstlisting}[caption={Function for the graphical display of data.}, label=sineplotfunctionlisting] function plotFunction(x_data, y_data, name) % Plots x-data against y-data and sets the display name. % @@ -1483,31 +1497,41 @@ end \end{lstlisting} -\paragraph{III. Erstellen eines Skriptes zur Koordinierung} -Die letzte Aufgabe ist die Koordinierung der Berechung und des -Plottens f\"ur mehrere Amplituden. Das ist die klassische Aufgabe -f\"ur ein \codeterm{Skript}. Auch hier gilt es einen ausdrucksvollen -Name zu finden. Da es keine Argumente und R\"uckgabewerte gibt, -m\"ussen die ben\"otigten Informationen direkt in dem Skript -defniniert werden. Es werden ben\"otigt: ein Vektor f\"ur die -Amplituden, je eine Variable f\"ur die gew\"unschte Frequenz, die -maximale Zeit auf der x-Achse und die zeitliche Aufl\"osung. Das -Skript \"offnet schlie{\ss}lich noch eine neue Abbildung mit -\code{figure()} und setzt das \code{hold on} da nur das Skript -wei{\ss}, das mehr als ein Plot erzeugt werden soll. Das Skript ist in -Listing \ref{sinesskriptlisting} dargestellt. - -\begin{lstlisting}[caption={Kontrollskript zur Koordination von Berechnung und graphischer Darstellung.},label=sinesskriptlisting] +\paragraph{III. One script to rule them all} + +The last task is to write a script to control the calculations and the +plotting of the sine waves. Classically, such controlling of sub-tasks +is handled in a script. It could be done with a function but if +there is a reason for the existence of scripts then it is this. + +Again, we need to specify what needs to be done: +\begin{enumerate} +\item The task is to display multiple sine waves. We want to have a + fixed frequency but there should be various amplitudes displayed. An + appropriate name for the script (that is the name of the m-file) + might be \file{plotMultipleSinewaves.m}. +\item What information do we need? we need to define the + \code{frequency}, the range of \code{amplitudes}, the + \code{duration} of the sine waves, and the temporal resolution given + as the time between to points in time, i.e. the \code{stepsize}. +\item We then need to create an empty figure, and work through the + rang of \code{amplitudes}. We must not forget to switch \code{hold + on} if we want to see all the sine waves in one plot. +\end{enumerate} + +The implementation is shown in listing~\ref{sinesskriptlisting}. + +\begin{lstlisting}[caption={Control script for the plotting of sine waves.},label=sinesskriptlisting] amplitudes = 0.25:0.25:1.25; frequency = 2.0; -t_max = 10.0; -t_step = 0.01; +duration = 10.0; % seconds +stepsize = 0.01; % seconds figure() hold on for i = 1:length(amplitudes) [x_data, y_data] = sinewave(frequency, amplitudes(i), ... - t_max, t_step); + duration, stepsize); plotFunction(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',... frequency, amplitudes(i))) end @@ -1516,34 +1540,42 @@ legend('show') \end{lstlisting} \begin{exercise}{plotMultipleSinewaves.m}{} - Erweiter das Programm so, dass die Sinusse f\"ur einen Satz von - Frequenzen geplottet wird. + Extend the program to plot also a range of frequencies. \pagebreak[4] \end{exercise} -\subsection{Einsatz von Funktionen und Skripten} - -Funktionen sind kleine Codefragmente, die im Idealfall genau eine -Aufgabe erledigen. Sie besitzen einen eigenen -\determ{G\"ultigkeitsbereich}, das hei{\ss}t, dass Variablen aus dem -globalen Workspace nicht verf\"ugbar sind und Variablen, die lokal in -der Funktion erstellt werden nicht im globalen Workspace sichtbar -werden. Dies hat zur Folge, dass Funktionen all die Informationen, die -sie ben\"otigen, von au{\ss}en erhalten m\"ussen. Sie nehmen -\determ{Argumente} entgegen und k\"onnen \determ{R\"uckgabwerte} -zur\"uckliefern. - -Die Verwendung von Funktionen ist der Verwendung von Skripten fast -immer vorzuziehen sind. Das hei{\ss}t aber nicht, das Skripte zu -verteufeln w\"aren und und vermieden werden sollten. In Wahrheit sind -beide daf\"ur gemacht, Hand in Hand ein Problem zu l\"osen. W\"ahrend -die Funktionen relativ kleine ``verdauliche'' Teilprobleme l\"osen, -werden Skripte eingesetzt um den Rahmen zu bilden und den Ablauf zu -koordinieren (Abbildung \ref{programlayoutfig}). -\begin{figure} - \includegraphics[width=0.5\columnwidth]{simple_program.pdf} - \titlecaption{Ein typisches Programmlayout.}{Das Kontrollskript - koordiniert den Aufruf der Funktionen, \"ubergibt Argumente und - nimmt R\"uckgabewerte entgegen.}\label{programlayoutfig} -\end{figure} +\begin{ibox}[t]{\label{whenscriptsbox}When to use scripts and functions} + + It is easily possible to solve any programming problem only with + functions. Avoiding functions is also possible but ends very messy + and extremely hard to debug when the project grows. The effort for + avoiding naming conflicts or cleaning up the workspace increases + with the size of the project. Generally, functions should be + preferred over scripts in almost all cases. There are, however, + situations when a script offers advantages. + + + \begin{minipage}{0.5\textwidth} + \includegraphics[width=0.9\columnwidth]{simple_program} + \end{minipage} + \begin{minipage}{0.5\textwidth} + \textbf{Controlling a task} that involves calling sub-routines, as + we did above, is one of these situations (see figure). The script + calls functions and takes care of passing the right arguments and + storing the return values. During the development phase a script + grows as one \emph{interactively} works on the command + line. Commands that have been tested are then transferred to the + script. + \end{minipage}\vspace{0.25cm} + Interactive programming is one of the main strengths of + \matlab{}. Interactive refers to the interaction between the + commands executed on the command line and the variables stored in + the workspace. The immediate feedback if a certain operation works + on the data stored in a variable or if the returned results are + correct speeds up the developmental progress. + + As soon as there is code duplication in a script or it grows too + large, it is high time to consider extracting features into separate + functions. +\end{ibox}