[translation] scripts and functions done... maybe

This commit is contained in:
Jan Grewe 2016-10-14 12:16:43 +02:00
parent 40d2eb4aa0
commit d23c2f577e
2 changed files with 130 additions and 94 deletions

View File

@ -29,6 +29,10 @@
\item Doppelte for-Schleife \item Doppelte for-Schleife
\item File output and input (load, save, fprintf, scanf) (extra chapter?) \item File output and input (load, save, fprintf, scanf) (extra chapter?)
\item help() und doc() \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{itemize}
\end{document} \end{document}

View File

@ -15,7 +15,7 @@ variable is read from the memory, this binary pattern is interpreted
according to the data type. The example shown in according to the data type. The example shown in
figure~\ref{variablefig} shows that the very same bit pattern is either 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 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 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. 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 The length of a vector, that is the number of elements, can be
requested using the \code{length()} or \code{numel()} requested using the \code{length()} or \code{numel()}
functions. \code{size()} provides the same information in a slightly, 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: used vector \varcode{a} has the following size:
\begin{lstlisting}[label=vectorsizeslisting, caption={Size of a vector.}] \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 results in a \code{logical} vector of the same size (see
listing~\ref{booleanexpressions}. This logical vector is then used to listing~\ref{booleanexpressions}. This logical vector is then used to
select only those values for which the logical vector is true. Line 14 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} 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] \begin{lstlisting}[caption={Logical indexing.}, label=logicalindexing1]
>> x = randn(1, 6) % a vector with 6 random numbers >> 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 is important to note that the case expression always checks for
equality! Optional the case expressions may be followed by the keyword equality! Optional the case expressions may be followed by the keyword
\code{otherwise} which catches all cases that were not explicitly \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.}] \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 \emph{scripts} to store the solutions of the exercises. Any variable
that was created appeared in the \codeterm{workspace} and existed even that was created appeared in the \codeterm{workspace} and existed even
after the program was finished. This is very convenient but also bears 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 some risks. Consider the case that \file{script\_a.m} creates a
variable and assigns a value to it for later use. Now it calls a certain variable and assigns a value to it for later use. Now it calls
second program (\file{script_b.m}) that, by accident, uses the same a second program (\file{script\_b.m}) that, by accident, uses the same
variable name and assigns a different value to it. When variable name and assigns a different value to it. When
\file{script_b.m} is done, the control returns to \file{script_a.m} \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 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 contain a different value than expected. Bugs like this are hard to
track down since each of the programs alone is perfectly fine and find since each of the programs alone is perfectly fine and works as
works as intended. A solution for this problem are the intended. A solution for this problem are the
\codeterm[Function]{functions}. \codeterm[Function]{functions}.
\subsection{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 \[ y = f(x) \] Here, the mathematical function has the name $f$ and it
has one \codeterm{argument} $x$ that is transformed into the has one \codeterm{argument} $x$ that is transformed into the
function's output value $y$. In \matlab{} the syntax of a function 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} \end{itemize}
The following listing (\ref{badsinewavelisting}) shows a function that 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 function meineFirstFunction() % function head
t = (0:0.01:2); t = (0:0.01:2);
frequency = 1.0; frequency = 1.0;
@ -1407,36 +1408,36 @@ defined:
As indicated above the \code{myFirstFunction} does three things at As indicated above the \code{myFirstFunction} does three things at
once, it seems natural, that the task should be split up into three once, it seems natural, that the task should be split up into three
parts. (i) Calculation of the individual sine-wave defined by the parts. (i) Calculation of the individual sine waves defined by the
frequency and the amplitude (ii) graphical display of the data and frequency and the amplitudes (ii) graphical display of the data and
(iii) coordination of calculation and display. (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 define (i) how to name the function, (ii) which information it needs
(arguments), and (iii) what it should return to the caller. (arguments), and (iii) what it should return to the caller.
\begin{enumerate} \begin{enumerate}
\item \codeterm[Funktion!Name]{Name}: der Name sollte beschreiben, was \item \codeterm[Function!Name]{Name}: the name should be descriptive
die Funktion tut. In diesem Fall berechnet sie einen Sinus. Ein of the function's purpose, i.e. the calculation of a sine wave. A
geeigneter, kurzer Name w\"are also \code{sinewave()}. appropriate name might be \code{sinewave()}.
\item \codeterm[Funktion!Argumente]{Argumente}: die zu brechnende \item \codeterm[Function!Arguments]{Arguments}: What information does
Sinusschwingung sei durch ihre Frequenz und die Amplitude the function need to do the calculation? There are obviously the
bestimmt. Des Weiteren soll noch festgelegt werden, wie lang der frequency as well as the amplitude. Further we may want to be able
Sinus sein soll und mit welcher zeitlichen Aufl\"osung gerechnet to define the duration of the sine wave and the temporal
werden soll. Es werden also vier Argumente ben\"otigt, sie k\"onnten resolution. We thus need four arguments which should also named to
hei{\ss}en: \varcode{amplitude}, \varcode{frequency}, describe their content: \code{amplitude, frequency, t\_max,} and
\varcode{t\_max}, \varcode{t\_step}. \code{t\_step} might be good names.
\item \codeterm[Funktion!R{\"u}ckgabewerte]{R\"uckgabewerte}: Um den \item \codeterm[Function!Return values]{Return values}: For a correct
Sinus korrekt darstellen zu k\"onnen brauchen wir die Zeitachse und display of the data we need two vectors. The time, and the sine wave
die entsprechenden Werte. Es werden also zwei Variablen itself. We just need two return values: \varcode{time}, \varcode{sine}
zur\"uckgegeben: \varcode{time}, \varcode{sine}
\end{enumerate} \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) function [time, sine] = sinewave(frequency, amplitude, t_max, t_step)
% Calculate a sinewave of a given frequency, amplitude, % Calculate a sinewave of a given frequency, amplitude,
% duration and temporal resolution. % duration and temporal resolution.
@ -1452,23 +1453,36 @@ function [time, sine] = sinewave(frequency, amplitude, t_max, t_step)
% time: vector of the time axis % time: vector of the time axis
% sine: vector of the calculated sinewave % sine: vector of the calculated sinewave
time = (0:t_step:t_max); time = (0:t_step:t_max);
sine = sin(frequency .* time .* 2 * pi) .* amplitude; sine = sin(frequency .* time .* 2 .* pi) .* amplitude;
end end
\end{lstlisting} \end{lstlisting}
\paragraph{II. Plotten einer einzelnen Schwingung} \paragraph{II. Plotting a single sine wave}
Das Plotten der berechneten Sinuschwingung kann auch von einer The display of the sine waves can also be delegated to a function. We
Funktion \"ubernommen werden. Diese Funktion hat keine andere Aufgabe, can now decide whether we want the function to plot all sine waves at
als die Daten zu plotten. Ihr Name sollte sich an dieser Aufgabe once, or if we want design a function that plots a single sine wave
orientieren (z.B. \code{plotFunction()}). Um einen einzelnen Sinus and that we then call repeatedly for each frequency/amplitude
zu plotten werden im Wesentlichen die x-Werte und die zugeh\"origen combination. The most flexible approach is the latter and we will
y-Werte ben\"otigt. Da mehrere Sinus geplottet werden sollen ist es thus implement it this way. We might come up with the following
auch sinnvoll eine Zeichenkette f\"ur die Legende an die Funktion zu specification of the function:
\"ubergeben. Da diese Funktion keine Berechnung durchf\"uhrt wird kein
R\"uckgabewert ben\"otigt (Listing \ref{sineplotfunctionlisting}). \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={Funktion zur graphischen Darstellung der Daten.}, label=sineplotfunctionlisting] \begin{lstlisting}[caption={Function for the graphical display of data.}, label=sineplotfunctionlisting]
function plotFunction(x_data, y_data, name) function plotFunction(x_data, y_data, name)
% Plots x-data against y-data and sets the display name. % Plots x-data against y-data and sets the display name.
% %
@ -1483,31 +1497,41 @@ end
\end{lstlisting} \end{lstlisting}
\paragraph{III. Erstellen eines Skriptes zur Koordinierung} \paragraph{III. One script to rule them all}
Die letzte Aufgabe ist die Koordinierung der Berechung und des
Plottens f\"ur mehrere Amplituden. Das ist die klassische Aufgabe The last task is to write a script to control the calculations and the
f\"ur ein \codeterm{Skript}. Auch hier gilt es einen ausdrucksvollen plotting of the sine waves. Classically, such controlling of sub-tasks
Name zu finden. Da es keine Argumente und R\"uckgabewerte gibt, is handled in a script. It could be done with a function but if
m\"ussen die ben\"otigten Informationen direkt in dem Skript there is a reason for the existence of scripts then it is this.
defniniert werden. Es werden ben\"otigt: ein Vektor f\"ur die
Amplituden, je eine Variable f\"ur die gew\"unschte Frequenz, die Again, we need to specify what needs to be done:
maximale Zeit auf der x-Achse und die zeitliche Aufl\"osung. Das \begin{enumerate}
Skript \"offnet schlie{\ss}lich noch eine neue Abbildung mit \item The task is to display multiple sine waves. We want to have a
\code{figure()} und setzt das \code{hold on} da nur das Skript fixed frequency but there should be various amplitudes displayed. An
wei{\ss}, das mehr als ein Plot erzeugt werden soll. Das Skript ist in appropriate name for the script (that is the name of the m-file)
Listing \ref{sinesskriptlisting} dargestellt. might be \file{plotMultipleSinewaves.m}.
\item What information do we need? we need to define the
\begin{lstlisting}[caption={Kontrollskript zur Koordination von Berechnung und graphischer Darstellung.},label=sinesskriptlisting] \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; amplitudes = 0.25:0.25:1.25;
frequency = 2.0; frequency = 2.0;
t_max = 10.0; duration = 10.0; % seconds
t_step = 0.01; stepsize = 0.01; % seconds
figure() figure()
hold on hold on
for i = 1:length(amplitudes) for i = 1:length(amplitudes)
[x_data, y_data] = sinewave(frequency, amplitudes(i), ... [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',... plotFunction(x_data, y_data, sprintf('freq: %5.2f, ampl: %5.2f',...
frequency, amplitudes(i))) frequency, amplitudes(i)))
end end
@ -1516,34 +1540,42 @@ legend('show')
\end{lstlisting} \end{lstlisting}
\begin{exercise}{plotMultipleSinewaves.m}{} \begin{exercise}{plotMultipleSinewaves.m}{}
Erweiter das Programm so, dass die Sinusse f\"ur einen Satz von Extend the program to plot also a range of frequencies.
Frequenzen geplottet wird.
\pagebreak[4] \pagebreak[4]
\end{exercise} \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} \begin{ibox}[t]{\label{whenscriptsbox}When to use scripts and functions}
\includegraphics[width=0.5\columnwidth]{simple_program.pdf}
\titlecaption{Ein typisches Programmlayout.}{Das Kontrollskript It is easily possible to solve any programming problem only with
koordiniert den Aufruf der Funktionen, \"ubergibt Argumente und functions. Avoiding functions is also possible but ends very messy
nimmt R\"uckgabewerte entgegen.}\label{programlayoutfig} and extremely hard to debug when the project grows. The effort for
\end{figure} 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}