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}
|
||||
\item Die Struktur von Programmen.
|
||||
\item Die Namensgebung von Skripten und Funktionen.
|
||||
\item Die Namensgebung fuer Variablen und Konstanten.
|
||||
\item Die Verwendung von Einr\"uckungen und Leerzeilen um Bl\"ocke im Code hervorzuheben.
|
||||
\item Die Namensgebung f\"ur Variablen und Konstanten.
|
||||
\item Die Verwendung von Einr\"uckungen und Leerzeilen um Bl\"ocke im
|
||||
Code hervorzuheben.
|
||||
\item Verwendung von Kommentaren und Hilfetexten.
|
||||
\item Auslagerung von Funktionalit\"at in eigene Funktionen.
|
||||
\end{enumerate}
|
||||
|
||||
\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
|
||||
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
|
||||
Variation des Namens ist nat\"urlich nicht sinnvoll. Sie tr\"agt keine
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
\TODO chaotisches und aufger\"aumtes Listing
|
||||
Die beiden folgenden Listings \ref{chaoticcode} und \ref{cleancode}
|
||||
zeigen die Implementation des random-walk einmal eher chaotisch und
|
||||
einmal aufger\"aumt.
|
||||
|
||||
\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}
|
||||
|
||||
@ -190,8 +233,8 @@ Variablennamen sind viel Zeilen weitestgehend selbsterkl\"arend.
|
||||
\begin{itemize}
|
||||
\item Kommentare sind gut und wichtig aber: Sie m\"ussen richtig
|
||||
sein!
|
||||
\item Ein Kommentar der l\"ugt, ist schlimmer als gar kein Kommentar!
|
||||
\item Kommentare m\"ussen gepflegt werden sonst sind sie mehr als
|
||||
\item Ein Kommentar, der l\"ugt, ist schlimmer als gar kein Kommentar!
|
||||
\item Kommentare m\"ussen gepflegt werden, sonst sind sie mehr als
|
||||
wertlos!
|
||||
\end{itemize}
|
||||
\end{important}
|
||||
@ -199,30 +242,86 @@ Variablennamen sind viel Zeilen weitestgehend selbsterkl\"arend.
|
||||
|
||||
\section{Auslagerung von Aufgaben in Funktionen}
|
||||
|
||||
Spaghetticode
|
||||
|
||||
inline functions
|
||||
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.
|
||||
|
||||
\section{Besonderheiten bei Skripten}
|
||||
\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}
|
||||
|
||||
Achtung, globaler G\"ultigkeitsbereich!
|
||||
\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.
|
||||
|
||||
Kollision von Variablennamen.
|
||||
\section{Besonderheiten bei Skripten}
|
||||
|
||||
Best practice.
|
||||
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}
|
||||
Programmcode soll lesbar sein. Namen von Variablen, Funktionen und
|
||||
Skripten sollten ausdrucksstark sein und R\"uckschl\"usse auf den
|
||||
Inhalt oder den Zweck erlauben. Einen pers\"onlichen Programmierstil
|
||||
zu entwickeln ist v\"ollig in Ordnung solange er konsistent ist. In
|
||||
machen Programmiersprachen gibt es Traditionen und
|
||||
\"Ubereink\"unfte, diese sollten dann beachtet werden.
|
||||
|
||||
Es lohnt sich!
|
||||
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.
|
||||
|
||||
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}
|
||||
|
||||
\section{Fazit}
|
||||
|
||||
Programmcode soll lesbar sein. Namen von Variablen, Funktionen und
|
||||
Skripten sollten ausdrucksstark sein und R\"uckschl\"usse auf den
|
||||
Inhalt oder den Zweck erlauben. Einen pers\"onlichen Programmierstil
|
||||
zu entwickeln ist v\"ollig in Ordnung solange er konsistent ist. In
|
||||
machen Programmiersprachen gibt es Traditionen und \"Ubereink\"unfte,
|
||||
diese sollten dann beachtet werden.
|
||||
|
||||
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
|
||||
Code: A Handbook of Agile Software Craftmanship}, Prentice Hall
|
||||
\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}
|
||||
|
Reference in New Issue
Block a user