[translation] scripts and functions done... maybe
This commit is contained in:
parent
40d2eb4aa0
commit
d23c2f577e
@ -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}
|
||||
|
@ -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}).
|
||||
\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={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)
|
||||
% 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}
|
||||
|
Reference in New Issue
Block a user