\chapter{Debugging}

\shortquote{60\% of coding time is finding errors}{Famous last words}

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 eigenen
\file{Documents} (Linux) oder \file{Eigene Dokumente} (Windows)
Ordner. Es bietet sich an, diesen Ordner als Wurzelverzeichnis f\"ur
eigene Arbeiten zu verwenden. Nat\"urlich kann auch jeder andere Ort
gew\"ahlt werden. In dem Beispiel in \figref{fileorganizationfig} wird
innerhalb dieses Ordners f\"ur jedes Projekt ein eigener Unterordner
erstellt, in welchem wiederum f\"ur jedes Problem, jede Analyse ein
weiterer Unterodner erstellt wird. In diesen liegen sowohl die
ben\"otigten \codeterm{m-files} also auch die Resultate der Analyse
(Abbildungen, Daten-Dateien). Zu bemerken sind noch zwei weitere
Dinge. Im Projektordner existiert ein Skript (analysis.m), das dazu
gedacht ist, alle Analysen aufzurufen. Des Weiteren gibt es parallel
zu den Projektordnern einen \file{functions}-Ordner in dem Funktionen
liegen, die in mehr als einem Projekt oder einer Analyse gebraucht
werden.

Beim Betrachten dieses Layouts 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
\file{load\_data.m} Funktion in jeder Analyse vorkommt. In der Regel
wird dies nicht zu Konflikten f\"uhren, da \matlab{} zuerst im
aktuellen Ordner nach passenden Dateien sucht (mehr Information zum
\matlab-Suchpfad in Box~\ref{matlabpathbox}).

\begin{figure}[tp]
  \includegraphics[width=0.75\textwidth]{no_bug}
  \titlecaption{\label{fileorganizationfig} M\"ogliche Organisation 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}[tp]{\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.

  Der Suchpfad kann sowohl \"uber die Kommandozeile mit dem Kommandos
  \code{addpath()} und \code{userpath()} als auch\"uber die in der
  Abbildung gezeigte GUI angezeigt und eingestellt werden. Die GUI
  erlaubt Ordner aus dem Suchpfad zu entfernen, neue Ordner (optional
  inklusive aller Unterordner) hinzuzuf\"ugen oder die Reihenfolge der
  Pfade zu ver\"andern.

  Zum Wechseln des aktuellen Arbeitsverzeichnisses wird das Kommando
  \code{cd} verwendet. \code{which} zeigt an, in welchem Pfad eine
  bestimmte Funktion gefunden wurde. 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 des
Namens. Dabei spielt die Gro{\ss}- und Kleinschreibung eine Rolle. Die
beiden Dateien \file{test\_funktion.m} und \file{Test\_Funktion.m}
zwei unterschiedliche Funktionen benennen k\"onnen. Diese Art der
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 --- manchmal ist es
sogar der schwierigste Aspekt des Programmierens!  Ausdrucksstarke
Namen zu finden lohnt sich aber. Ausdrucksstark bedeutet, dass sich
aus dem Namen R\"uckschl\"usse auf den Zweck ziehen lassen sollte.

\begin{important}[Benennung von Funktionen und Skripten]
  Die Namen von Funktionen und Skripten sollten m\"oglichst viel \"uber
  die Funktionsweise oder den Zweck aussagen (\file{firingrates.m}
  statt \file{uebung.m}). Gute Namen f\"ur Funktionen und Skripte sind
  die beste Dokumentation.
\end{important}

In Namen verbietet \matlab{} verbietet Leerzeichen, Sonderzeichen und
Umlaute. Namen d\"urfen auch nicht mit Zahlen anfangen. Es mach f\"ur
die Namensgebung selbst keine weiteren Vorgaben. Allerdings folgt die
Benennung der in \matlab{} 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}


\begin{important}[Benennung von Variablen]
  Die Namen von Variablen sollten m\"oglichst viel \"uber ihren Inhalt
  aussagen (\varcode{spike\_count} statt \varcode{x}). Gute Namen
  f\"ur Variablen sind die beste Dokumentation.
\end{important}

 
\begin{lstlisting}[label=chaoticcode, caption={Un\"ubersichtliche Implementation des Random-walk.}]
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}

\pagebreak[4]

\begin{lstlisting}[label=cleancode, caption={\"Ubersichtliche Implementation des Random-walk.}]
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{exercise}{logicalVector.m}{logicalVector.out}
%   Erstelle einen Vektor \varcode{x} mit den Werten 0--10.
%   \begin{enumerate}
%   \item F\"uhre aus: \varcode{y = x < 5}
%   \item Gib den Inhalt von \varcode{y} auf dem Bildschirm aus.
%   \item  Was ist der Datentyp von \varcode{y}?
%   \item  Gibt alle Elemente aus \varcode{x} zur\"uck, die kleiner als 5 sind.
%   \end{enumerate}
%   \pagebreak[4]
% \end{exercise}
