229 lines
10 KiB
TeX
229 lines
10 KiB
TeX
\chapter{\tr{Programming style}{Programmierstil}}
|
|
|
|
Guter Programmierstil ist keine Frage des guten Geschmacks sondern des
|
|
Verst\"andnisses von Programmcode und ein Baustein in dem Bestreben
|
|
wissenschaftlichen Erkenntnisgewinn reproduzierbar zu
|
|
machen.
|
|
|
|
Programme sollten so geschrieben und strukturiert sein, dass es sowohl
|
|
einem Au{\ss}enstehenden als auch einem selbst, nach ein paar Monaten,
|
|
leicht f\"allt den Programmablauf nachzuvollziehen und zu
|
|
verstehen. Saubere Programmierung zahlt sich auch f\"ur den Sch\"opfer
|
|
eines Programmes aus.
|
|
|
|
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 Verwendung von Kommentaren und Hilfetexten.
|
|
\end{enumerate}
|
|
|
|
\section{Struktur von Programmen, Organisation von m-Files im Dateisystem}
|
|
|
|
In der Einf\"uhrung zu Funktionen und Skripten wurde schon einmal ein
|
|
typisches Programmlayout vorgestellt (Abbildung
|
|
\ref{programlayoutfig}). Hier wurde vorgeschlagen ein Skript als
|
|
Kontrollskript zu verwenden. Dieses kontrolliert den weiteren
|
|
Programmablauf, ruft Funktionen auf, \"ubergibt Argumente und nimmt
|
|
R\"uckgabewerte entgegen. Eine solche Struktur macht es einfach den
|
|
Ablauf zu verstehen. Es bleibt aber die Frage, wie man das
|
|
Kontrollskript unter den anderen \codeterm{m-files} als solches
|
|
erkennt. Um dieses zu erleichtern gilt es zwei Dinge zu beachten:
|
|
1. Wie werden Programme im Dateisystem organisiert? 2. Wie werden
|
|
Programme benannt?
|
|
|
|
Es hilft ungemein, wenn zusammengeh\"orige Skripte und Funktionen im
|
|
gleichen Ordner auf der Festplatte zu finden sind. Es bietet sich also
|
|
an f\"ur jede Analyse einen eigenen Ordner anzulegen und in diesem die
|
|
zugeh\"origen \codeterm{m-files} abzulegen. Auf eine tiefere
|
|
Schachtelung in weitere Unterordner kann in der Regel verzichtet
|
|
werden. \matlab{} erzeugt einen ``MATLAB'' Ordner im eingenen
|
|
``Documents'' (Linux) oder ``Eigene Dokumente'' (Windows) Ordner. Es
|
|
bietet sich an diesen als Wurzelverzeichnis f\"ur eigene Arbeiten zu
|
|
verwenden. Nat\"urlich kann auch jeder andere Ort gew\"ahlen
|
|
werden. In dem Beispiel in Abbildung \ref{fileorganizationfig} wird
|
|
innerhalb dieses Ordners f\"ur jedes Projekt ein eigener Unterordner
|
|
erstellt in welchem widerum f\"ur jedes Problem, jede Analyse ein
|
|
weitere Unterodner erstellt wird. In diesen liegen sowohl die
|
|
ben\"otigten m-files also auch die Resultate der Analyse (Abbildungen,
|
|
Dateien). Zu bemerken sind noch zwei weitere Dinge. Im Projektordner
|
|
existiert ein Skript (analysis.m), das dazu gedacht ist, alle Analysen
|
|
aufzurufen. Des Weiteren gitb es parallel zu den Projektordnern einen
|
|
``functions'' Ordner in dem Funktionen liegen, die in mehr als einem
|
|
Projekt oder einer Analyse gebraucht werden.
|
|
|
|
Wenn man sich dieses Layout anschaut f\"allt auf, dass es sehr
|
|
wahrscheinlich ist, dass bestimmte Namen f\"ur Funktionen und Skripte
|
|
mehrfach verwendet werden. Es ist nicht verwunderlich, wenn eine
|
|
``load\_data.m'' Funktion in jeder Analyse vorkommt. In der Regel wird
|
|
dies nicht zu Konflikten f\"uhren, da \matlab{} zuforderst im
|
|
aktuellen Ordner nach passenden Dateien sucht (mehr Information in Box
|
|
\ref{matlabpathbox}).
|
|
|
|
\begin{figure}
|
|
\includegraphics[width=0.75\textwidth]{program_organization}
|
|
\titlecaption{\label{fileorganizationfig} M\"ogliche Oganisation von
|
|
Programmcode im Dateisystem.}{ F\"ur jedes Projekt werden
|
|
Unterordner f\"ur die einzelnen Analysen angelegt. Auf Ebene des
|
|
Projektes k\"onnte es ein Skript (hier ``analysis.m'') geben,
|
|
welches alle Analysen in den Unterordnern anst\"o{\ss}t.}
|
|
\end{figure}
|
|
|
|
|
|
\begin{ibox}[t]{\label{matlabpathbox}Der \matlab{} Suchpfad}
|
|
Der Suchpfad definiert, wo \matlab{} nach Skripten und Funktionen
|
|
sucht. Wird eine Funktion aufgerufen wird zun\"achst im aktuellen
|
|
Arbeitsverzeichnis einem Treffer gesucht. Schl\"agt diese Suche
|
|
fehl, so arbeitet sich \matlab{} durch den \codeterm{Suchpfad}
|
|
(siehe Abbildung). Der \codeterm{Suchpfad} ist eine Liste von
|
|
Ordnern in denen \matlab{} nach Funktionen und Skripten suchen
|
|
soll. Die Suche nach der aufgerufenen Funktion wird dabei von oben
|
|
nach unten durchgef\"uhrt. Das heisst, dass es, bei
|
|
Namensgleichheit, eine Rolle spielen kann an welcher Stelle im
|
|
Suchpfad der erste Treffer gefunden wird. Wichtig: \matlab{} sucht
|
|
nicht rekursiv! Wenn die gew\"unschte Funktion in einem Unterordner
|
|
des aktuellen Arbeitsverzeichnisses liegt, dieses aber nicht
|
|
explizit im Suchpfad enthalten ist, so wird die Funktion nicht
|
|
gefunden werden.
|
|
|
|
\includegraphics[width=0.75\textwidth]{search_path}
|
|
|
|
Man kann den Suchpfad sowohl \"uber die in der Abbildung gezeigte
|
|
GUI oder auch \"uber die Kommandozeile editieren. In der GUI hat man
|
|
die M\"oglichkeit Ordner aus dem Suchpfad zu entfernen, neue Ordner
|
|
(optional inklusive aller Unterordner) hinzuzuf\"ugen oder die
|
|
Reihenfolge zu ver\"andern.
|
|
|
|
Will man das aktuelle Arbeitsverzeichis wechseln benutzt man das
|
|
Kommando \code{cd}, um herauszufinden, in welchem Pfad eine
|
|
bestimmte Funktion gefunden wurde, benutzt man das Kommando
|
|
\code{which}. Der das aktuelle Areitsverzeichnis wird durch den
|
|
Aufruf \code{pwd} auf der Kommandozeile ausgegeben.
|
|
\end{ibox}
|
|
|
|
\section{Namensgebung von Funktionen und Skripten}
|
|
|
|
\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''
|
|
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
|
|
der Name nahezu nichts \"uber den Zweck der Funktion aus. Die
|
|
Namensgebung f\"allt mitunter nicht leicht, es lohnt sich aber
|
|
ausdruckstarke Namen zu finden. Ausdrucksstark bedeutet, dass sich aus
|
|
dem Namen ein R\"uckschluss auf den Zweck ziehen lassen sollte.
|
|
|
|
\matlab{} macht keine weiteren Vorgaben, was die Namen
|
|
angeht. Allerdings folgt die Benennung der vordefinierten Funktionen
|
|
gewissen Mustern:
|
|
\begin{itemize}
|
|
\item Namen werden immer klein geschrieben.
|
|
\item Es werden gerne Abk\"urzungen eingesetzt (z.B. \code{xcorr}
|
|
f\"ur die Kreuzkorrelation oder \code{repmat} f\"ur ``repeat matrix'')
|
|
\item Funktionen, die zwischen Formaten konvertieren sind immer nach
|
|
dem Muster ``format2format'' (z.B. \code{num2str} f\"ur die
|
|
Konvertierung ``number to string'', Umwandlung eines numerischen
|
|
Wertes in einen Text) benannt.
|
|
\end{itemize}
|
|
|
|
Andere \"ubliche Muster sind der \emph{camelCase} bei dem die
|
|
Anf\"ange zusammengesetzter Worte jeweils gro{\ss} geschrieben werden
|
|
oder auch die Verwendung von Unterstrichen zur Trennung von
|
|
Namenskomponenten. Eine Funktion, die die Anzahl Aktionspotentiale
|
|
berechnet k\"onnte etwa \codeterm{spikeCount.m} oder auch
|
|
\codeterm{spike\_count.m} benannt werden. Leerzeichen, Sonderzeichen
|
|
oder Anf\"ange mit Zahlen sind in Namen nicht erlaubt.
|
|
|
|
|
|
\section{Namensgebung von Variablen und Konstanten}
|
|
|
|
F\"ur die Bennennung von Variablen und Konstanten gelten die gleichen
|
|
Regeln wie f\"ur die Namen von Funktionen und Skripten. Die Maxime von
|
|
gutem Programmierstil ist: \emph{``Programmcode muss lesbar
|
|
sein.''}. Dabei helfen gute Namen ungemein. Auch wenn es schwer
|
|
f\"allt passende Namen zu finden, die nicht zu lang werden sollte man
|
|
sich auch da M\"uhe geben.
|
|
|
|
Bei den Funktionen und Skripten fragt man danach, welchen Zweck sie
|
|
erf\"ullen, bei Variablen fragt man nach dem Inhalt. Eine Varaible die
|
|
die mittlere Anzahl Aktionspotentiale speichert k\"onnte also
|
|
\codeterm{average\_spike\_count} hei{\ss}en. Wenn die Variable nicht nur
|
|
einen sondern mehrere Werte aufnimmt, dann ist der Plural angebracht
|
|
(\codeterm{average\_spike\_counts}).
|
|
|
|
|
|
\section{Codestil}
|
|
|
|
Die Lesbarkeit von Programmen wird sehr durch den Codestil
|
|
beeinflusst. Ein Programm, in dem z.B. Schleifenk\"orper nicht (oder
|
|
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
|
|
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
|
|
leicht den \"Uberblick verliert.
|
|
|
|
|
|
\TODO chaotisches und aufger\"aumtes Listing
|
|
|
|
\section{Verwendung von Kommentaren}
|
|
|
|
Kommentare k\"onnen ebenfalls sehr zum Verst\"andnis beitragen. Bei
|
|
allen vordefinierten \matlab{} Funktionen findet sich am Anfang eine
|
|
Kommentarblock, der den Zweck der Funktion, die verschiedenen
|
|
M\"oglichkeiten des Funktionsaufrufs und die Argumente und
|
|
R\"uckgabewerte beschreibt. Auch in eingenen Funktionen, vor allem
|
|
wenn auch andere Personen sie benutzen sollen, sind diese Kommentare
|
|
hilfreich. H\"aufig werden kurze Kommentare eingesetzt um Abschnitte
|
|
im Programm zu trennen. Hierbei sollte man auch sparsam sein. Jede
|
|
Zeile zu erkl\"aren kann in der Entwicklungsphase eines Programms sehr
|
|
hilfreich sein, bl\"aht aber den Code auf und bei der Verwendung guter
|
|
Variablennamen sind viel Zeilen weitestgehend selbsterkl\"arend.
|
|
|
|
\begin{important}
|
|
\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
|
|
wertlos!
|
|
\end{itemize}
|
|
\end{important}
|
|
|
|
|
|
\section{Auslagerung von Aufgaben in Funktionen}
|
|
|
|
Spaghetticode
|
|
|
|
inline functions
|
|
|
|
|
|
\section{Besonderheiten bei Skripten}
|
|
|
|
Achtung, globaler G\"ultigkeitsbereich!
|
|
|
|
Kollision von Variablennamen.
|
|
|
|
Best practice.
|
|
|
|
\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!
|
|
\end{important}
|
|
|
|
|
|
Literatur zum Programmierstil: z.B. Robert C. Martin: \textit{Clean
|
|
Code: A Handbook of Agile Software Craftmanship}, Prentice Hall
|