This repository has been archived on 2021-05-17. You can view files and clone it, but cannot push or open issues or pull requests.
scientificComputing/programmingstyle/lecture/programmingstyle.tex
2015-11-14 01:50:28 +01:00

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