finished (?) chapter, add example code
This commit is contained in:
parent
9af291738f
commit
108210210a
30
programmingstyle/code/calculate_sines.m
Normal file
30
programmingstyle/code/calculate_sines.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function sines = calculate_sines(x, amplitudes, frequencies)
|
||||||
|
% Function calculates sinewaves with all combinations of
|
||||||
|
% given amplitudes and frequencies.
|
||||||
|
% Arguments: x, a vector of radiants for which the sine should be
|
||||||
|
% computed
|
||||||
|
% amplitudes, a vector of amplitudes
|
||||||
|
% frequencies, a vector of frequencies
|
||||||
|
%
|
||||||
|
% Returns: a 3-D Matrix of sinewaves, 2nd dimension represents
|
||||||
|
% the amplitudes, 3rd the frequencies.
|
||||||
|
|
||||||
|
sines = zeros(length(x), length(amplitudes), length(frequencies));
|
||||||
|
|
||||||
|
for i = 1:length(amplitudes)
|
||||||
|
sines(:, i, :) = sines_with_frequencies(x, amplitudes(i), frequencies);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function sines = sines_with_frequencies(x, amplitude, frequencies)
|
||||||
|
sines = zeros(length(x), length(frequencies));
|
||||||
|
for i = 1:length(frequencies)
|
||||||
|
sines(:,i) = sinewave(x, amplitude, frequencies(i));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function sine = sinewave(x, amplitude, frequency)
|
||||||
|
sine = sin(2 .* pi .* x *frequency) .* amplitude;
|
||||||
|
end
|
@ -15,9 +15,11 @@ Guter Programmierstil greift auf unterschiedlichen Ebenen an:
|
|||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Die Struktur von Programmen.
|
\item Die Struktur von Programmen.
|
||||||
\item Die Namensgebung von Skripten und Funktionen.
|
\item Die Namensgebung von Skripten und Funktionen.
|
||||||
\item Die Namensgebung fuer Variablen und Konstanten.
|
\item Die Namensgebung f\"ur Variablen und Konstanten.
|
||||||
\item Die Verwendung von Einr\"uckungen und Leerzeilen um Bl\"ocke im Code hervorzuheben.
|
\item Die Verwendung von Einr\"uckungen und Leerzeilen um Bl\"ocke im
|
||||||
|
Code hervorzuheben.
|
||||||
\item Verwendung von Kommentaren und Hilfetexten.
|
\item Verwendung von Kommentaren und Hilfetexten.
|
||||||
|
\item Auslagerung von Funktionalit\"at in eigene Funktionen.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
\section{Struktur von Programmen, Organisation von m-Files im Dateisystem}
|
\section{Struktur von Programmen, Organisation von m-Files im Dateisystem}
|
||||||
@ -107,7 +109,7 @@ aktuellen Ordner nach passenden Dateien sucht (mehr Information in Box
|
|||||||
|
|
||||||
\matlab{} sucht Funktionen und Skripte ausschlie{\ss}lich anhand der
|
\matlab{} sucht Funktionen und Skripte ausschlie{\ss}lich anhand der
|
||||||
Namen. Dabei spielt die Gro{\ss}- und Kleinschreibung eine Rolle. Das
|
Namen. Dabei spielt die Gro{\ss}- und Kleinschreibung eine Rolle. Das
|
||||||
hei{\ss}t, dass die Namen ``test_funktion.m'' und ``Test_funktion.m''
|
hei{\ss}t, dass die Namen ``test\_funktion.m'' und ``Test\_funktion.m''
|
||||||
zwei unterschiedliche Funktionen benennen k\"onnen. Diese Art
|
zwei unterschiedliche Funktionen benennen k\"onnen. Diese Art
|
||||||
Variation des Namens ist nat\"urlich nicht sinnvoll. Sie tr\"agt keine
|
Variation des Namens ist nat\"urlich nicht sinnvoll. Sie tr\"agt keine
|
||||||
Information \"uber den Unterschied der beiden Funktionen. Auch sagt
|
Information \"uber den Unterschied der beiden Funktionen. Auch sagt
|
||||||
@ -163,14 +165,55 @@ zuf\"allig) einger\"uckt sind ist deutlich schwerer zu lesen und zu
|
|||||||
verstehen, als eines, in dem eine konsistente Einr\"uckung vorgenommen
|
verstehen, als eines, in dem eine konsistente Einr\"uckung vorgenommen
|
||||||
wurde.
|
wurde.
|
||||||
|
|
||||||
Gerne werden Leerzeielen eingef\"ugt um Abschnitte im Programm zu
|
Gerne werden Leerzeilen eingef\"ugt um Abschnitte im Programm zu
|
||||||
trennen. Das ist v\"ollig ok, wenn es konsistent und sparsam benutzt
|
trennen. Das ist v\"ollig ok, wenn es konsistent und sparsam benutzt
|
||||||
wird. Hier sollte eine Leerzeile ausreichen. Zu gro{\ss}e Abst\"ande
|
wird. Hier sollte eine Leerzeile ausreichen. Zu gro{\ss}e Abst\"ande
|
||||||
f\"uhren dazu das das Programm nicht mehr auf eine Seite passt und man
|
f\"uhren dazu, dass das Programm nicht mehr auf eine Seite passt und man
|
||||||
leicht den \"Uberblick verliert.
|
leicht den \"Uberblick verliert.
|
||||||
|
|
||||||
|
Die beiden folgenden Listings \ref{chaoticcode} und \ref{cleancode}
|
||||||
|
zeigen die Implementation des random-walk einmal eher chaotisch und
|
||||||
|
einmal aufger\"aumt.
|
||||||
|
|
||||||
\TODO chaotisches und aufger\"aumtes Listing
|
\begin{lstlisting}[label=chaoticcode, caption={Random-walk Implementation unaufgr\"aumt.}]
|
||||||
|
num_runs = 10;
|
||||||
|
max_steps = 1000;
|
||||||
|
|
||||||
|
positions = zeros(max_steps, num_runs);
|
||||||
|
|
||||||
|
for run = 1:num_runs
|
||||||
|
|
||||||
|
|
||||||
|
for step = 2:max_steps
|
||||||
|
|
||||||
|
x = randn(1);
|
||||||
|
if x<0
|
||||||
|
positions(step, run)= positions(step-1, run)+1;
|
||||||
|
|
||||||
|
|
||||||
|
elseif x>0
|
||||||
|
positions(step,run)=positions(step-1,run)-1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{lstlisting}[label=cleancode, caption={Random-walk Implementation etwas ordentlicher.}]
|
||||||
|
num_runs = 10;
|
||||||
|
max_steps = 1000;
|
||||||
|
positions = zeros(max_steps, num_runs);
|
||||||
|
|
||||||
|
for run = 1:num_runs
|
||||||
|
for step = 2:max_steps
|
||||||
|
x = randn(1);
|
||||||
|
if x < 0
|
||||||
|
positions(step, run) = positions(step-1, run) + 1;
|
||||||
|
elseif x > 0
|
||||||
|
positions(step, run) = positions(step-1, run) - 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
\section{Verwendung von Kommentaren}
|
\section{Verwendung von Kommentaren}
|
||||||
|
|
||||||
@ -190,8 +233,8 @@ Variablennamen sind viel Zeilen weitestgehend selbsterkl\"arend.
|
|||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Kommentare sind gut und wichtig aber: Sie m\"ussen richtig
|
\item Kommentare sind gut und wichtig aber: Sie m\"ussen richtig
|
||||||
sein!
|
sein!
|
||||||
\item Ein Kommentar der l\"ugt, ist schlimmer als gar kein Kommentar!
|
\item Ein Kommentar, der l\"ugt, ist schlimmer als gar kein Kommentar!
|
||||||
\item Kommentare m\"ussen gepflegt werden sonst sind sie mehr als
|
\item Kommentare m\"ussen gepflegt werden, sonst sind sie mehr als
|
||||||
wertlos!
|
wertlos!
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{important}
|
\end{important}
|
||||||
@ -199,30 +242,86 @@ Variablennamen sind viel Zeilen weitestgehend selbsterkl\"arend.
|
|||||||
|
|
||||||
\section{Auslagerung von Aufgaben in Funktionen}
|
\section{Auslagerung von Aufgaben in Funktionen}
|
||||||
|
|
||||||
Spaghetticode
|
Kommentare oder Leerzeilen werden benutzt um Abschnitte des Codes
|
||||||
|
abzutrennen und nazudeuten, dass ab da etwas inhaltlich anderes
|
||||||
|
gemacht wird. Wenn man im Zuge ist, eine solche inhaltliche Trennung
|
||||||
|
einzuf\"ugen muss man sich immer fragen, ob dieser Teil des Programms
|
||||||
|
nicht in eine eigene Funktion ausgelagert werden sollte. Fast immer
|
||||||
|
kann man das bejahen.
|
||||||
|
|
||||||
|
Abschnitte nicht auszulagern f\"uhrt zu sehr langen m-Files, die
|
||||||
|
leicht un\"ubersichtlich sind. Man nennt sie
|
||||||
|
\codeterm{Spaghetticode}. Es ist h\"ochste Zeit \"uber Auslagerung in
|
||||||
|
Funktionen nachzudenken.
|
||||||
|
|
||||||
inline functions
|
\begin{important}
|
||||||
|
Wann sollte man Programmteile in eigene Funktionen auslagern?
|
||||||
|
\begin{itemize}
|
||||||
|
\item Wenn man innerhalb einer Funktion, eines Skripts mehr als zwei
|
||||||
|
Einr\"uckungsebenen hat.
|
||||||
|
\item Wenn man wiederholte Strukturen im Code hat.
|
||||||
|
\item Wenn man versucht ist, diese mit Copy and Paste zu erzeugen.
|
||||||
|
\end{itemize}
|
||||||
|
\end{important}
|
||||||
|
|
||||||
|
\subsection{Lokale Funktionen und geschachtelte Funktionen}
|
||||||
|
|
||||||
|
Eine M\"oglichkeit Spaghetticode zu vermeiden ist das Auslagern von
|
||||||
|
Funktionalit\"at in eigene Funktionen. Dies f\"uhrt dazu, dass man
|
||||||
|
eine F\"ulle von Dateien erzeugt, die die \"Ubersichtlichkeit nicht
|
||||||
|
unbedingt erh\"ohen. Wenn die auszulagernde Funktionalit\"at an vielen
|
||||||
|
Stellen ben\"otigt werden k\"onnte ist es dennoch sinnvol dies zu
|
||||||
|
tun. Wenn nicht, dann bietet \matlab{} die M\"oglichkeit sogenannte
|
||||||
|
\codeterm{lokale Funktionen} oder auch \codeterm{geschachtelte
|
||||||
|
Funktionen} (\enterm{nested functions}) zu erstellen (Listing
|
||||||
|
\ref{localfunctions} zeigt ein Beispiel f\"ur eine lokale Funktion).
|
||||||
|
|
||||||
|
\lstinputlisting[label=localfunctions, caption={\codeterm{Lokale Funktionen} erh\"ohen die Lesbarkeit sind aber nur innerhalb der definierenden Datei verf\"ugbar.}]{calculate_sines.m}
|
||||||
|
|
||||||
|
Lokale Funktionen existieren in der gleichen Datei und sind nur dort
|
||||||
|
verf\"ugbar. Jede Funktion hat ihren eigenen G\"ultigkeitsbereich, das
|
||||||
|
hei{\ss}t, dass Variablen aus den aufrufenden Funktionen nicht
|
||||||
|
sichtbar sind. Bei sogenannten \codeterm{geschachtelten Funktionen}
|
||||||
|
ist das anders. Diese werden innerhalb eines Funktionsk\"orpers
|
||||||
|
(zwischen den Schl\"usselworten \codeterm{function} und dem
|
||||||
|
\codeterm{end} definiert und k\"onnen auf alle Variablen der
|
||||||
|
``Mutterfunktion'' zugreifen und diese auch ver\"andern. Folglich
|
||||||
|
sollten sie nur mit Bedacht eingesetzt werden.
|
||||||
|
|
||||||
\section{Besonderheiten bei Skripten}
|
\section{Besonderheiten bei Skripten}
|
||||||
|
|
||||||
Achtung, globaler G\"ultigkeitsbereich!
|
Ein \"ahnliches Problem wurde schon bei der Einf\"uhrung der Skripte
|
||||||
|
erw\"ahnt. Variablen, die in Skripten definiert werden sind global im
|
||||||
|
\codeterm{Workspace} verf\"ugbar. Es besteht die Gefahr von
|
||||||
|
Namenskollisionen. Problem dabei ist, dass der Nutzer gar nicht
|
||||||
|
mitbekommt, wenn eine Variable redefiniert oder neuen Inhalt
|
||||||
|
zugewiesen bekommt. Fehler, die auf derartigen Kollisionen beruhen
|
||||||
|
sind h\"aufig nur schwer zu finden, da das Programm f\"ur sich korrekt
|
||||||
|
aussieht.
|
||||||
|
|
||||||
|
\begin{important}
|
||||||
|
Es empfiehlt sich zu Beginn eines Skriptes alle Variablen im
|
||||||
|
\codeterm{Workspace} zu l\"oschen (\code{clear}). Meist ist auch
|
||||||
|
ein \code{close all} angebracht.
|
||||||
|
|
||||||
Kollision von Variablennamen.
|
Am Ende eines Skriptes sollte der \codeterm{Workspace} mithilfe von
|
||||||
|
\code{clear} wieder von all den Variablen ges\"aubert werden, die
|
||||||
|
nicht mehr ben\"otigt werden.
|
||||||
|
\end{important}
|
||||||
|
|
||||||
Best practice.
|
\section{Fazit}
|
||||||
|
|
||||||
\begin{important}
|
|
||||||
Programmcode soll lesbar sein. Namen von Variablen, Funktionen und
|
Programmcode soll lesbar sein. Namen von Variablen, Funktionen und
|
||||||
Skripten sollten ausdrucksstark sein und R\"uckschl\"usse auf den
|
Skripten sollten ausdrucksstark sein und R\"uckschl\"usse auf den
|
||||||
Inhalt oder den Zweck erlauben. Einen pers\"onlichen Programmierstil
|
Inhalt oder den Zweck erlauben. Einen pers\"onlichen Programmierstil
|
||||||
zu entwickeln ist v\"ollig in Ordnung solange er konsistent ist. In
|
zu entwickeln ist v\"ollig in Ordnung solange er konsistent ist. In
|
||||||
machen Programmiersprachen gibt es Traditionen und
|
machen Programmiersprachen gibt es Traditionen und \"Ubereink\"unfte,
|
||||||
\"Ubereink\"unfte, diese sollten dann beachtet werden.
|
diese sollten dann beachtet werden.
|
||||||
|
|
||||||
Es lohnt sich!
|
|
||||||
\end{important}
|
|
||||||
|
|
||||||
|
Wiederholte Programmabschnitte sollten in Funktionen ausgelagert
|
||||||
|
werden. Wenn diese nich von globalem Interesse sind, kann man auch mit
|
||||||
|
\codeterm{lokalen} oder \codeterm{geschachtelten Funktionen} die
|
||||||
|
Lesbarkeit erh\"ohen.
|
||||||
|
|
||||||
Literatur zum Programmierstil: z.B. Robert C. Martin: \textit{Clean
|
\noindent Es lohnt sich auf den eigenen Programmierstil zu achten!\footnote{Literatur zum Programmierstil: z.B. Robert C. Martin: \textit{Clean
|
||||||
Code: A Handbook of Agile Software Craftmanship}, Prentice Hall
|
Code: A Handbook of Agile Software Craftmanship}, Prentice Hall}
|
||||||
|
Reference in New Issue
Block a user