[chapter 4] translate code style chapter
This commit is contained in:
		
							parent
							
								
									104717cfe7
								
							
						
					
					
						commit
						4270b65442
					
				| @ -1,215 +1,208 @@ | |||||||
| \chapter{\tr{Programming style}{Programmierstil}} | \chapter{\tr{Code style}{Programmierstil}} | ||||||
| 
 | 
 | ||||||
| \shortquote{Any code of your own that you haven't looked at for six or | \shortquote{Any code of your own that you haven't looked at for six or | ||||||
|   more months might as well have been written by someone |   more months might as well have been written by someone | ||||||
|   else.}{Eagleson's law} |   else.}{Eagleson's law} | ||||||
| 
 | 
 | ||||||
| \selectlanguage{ngerman} | %\selectlanguage{ngerman} | ||||||
|  | Cultivating a good code style not a matter of good taste but is | ||||||
|  | a key ingredient for understandability, maintainability and in the end | ||||||
|  | facilitates reproducibility of scientific results. Programs should be | ||||||
|  | written and structured in a way that supports outsiders as well the | ||||||
|  | author himself --- a few weeks or months after it was written --- to | ||||||
|  | understand the programs' rationale. Clean code pays off for the | ||||||
|  | original author as well as others that are supposed to use the code. | ||||||
| 
 | 
 | ||||||
| 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 | Clean code addresses several issues: | ||||||
| einem Au{\ss}enstehenden als auch einem selbst --- nach ein paar |  | ||||||
| Wochen oder Monaten! --- leicht f\"allt den Programmablauf |  | ||||||
| nachzuvollziehen und zu verstehen. Saubere Programmierung zahlt sich |  | ||||||
| in erster Linie f\"ur einen selbst aus und macht es aber gleichzeitig |  | ||||||
| f\"ur andere Personen leichter, den Code nachzuvollziehen und zu |  | ||||||
| benutzen. |  | ||||||
| 
 |  | ||||||
| Guter Programmierstil greift auf unterschiedlichen Ebenen an: |  | ||||||
| \begin{enumerate} | \begin{enumerate} | ||||||
| \item Die Dateistruktur von Programmen. | \item The programs' structure. | ||||||
| \item Die Namensgebung von Skripten und Funktionen.   | \item Naming of scripts and functions. | ||||||
| \item Die Namensgebung f\"ur Variablen und Konstanten. | \item Naming of variables and constants. | ||||||
| \item Die Verwendung von Einr\"uckungen und Leerzeilen um Bl\"ocke im | \item Application of indentation empty lines to define blocks. | ||||||
|   Code hervorzuheben. | \item Use of comments and inline documentation. | ||||||
| \item Verwendung von Kommentaren und Hilfetexten. | \item Delegation of repeated code to functions and dedicated | ||||||
| \item Auslagerung von Funktionalit\"at in eigene Funktionen. |   subroutines. | ||||||
| \end{enumerate} | \end{enumerate} | ||||||
| 
 | 
 | ||||||
| \section{Organisation von Programmdateien im Dateisystem} | \section{Organization of programs on the file system} | ||||||
| 
 | 
 | ||||||
| In der Einf\"uhrung zu Funktionen und Skripten wurde schon einmal ein | While introducing scripts and functions we suggested a typical program | ||||||
| typisches Programmlayout vorgestellt (box\,\ref{whenscriptsbox}). Hier | layout (box\,\ref{whenscriptsbox}). The idea is to create a single | ||||||
| wurde vorgeschlagen ein Skript als Kontrollskript zu verwenden. Dieses | entry point by having one script that controls the rest of program by | ||||||
| kontrolliert den weiteren Programmablauf, ruft Funktionen auf, | managing data and results and calling functions that work on the data | ||||||
| \"ubergibt Argumente und nimmt R\"uckgabewerte entgegen. Eine solche | and produce the results. Applying this structure makes it easy to | ||||||
| Struktur macht es einfach den Ablauf zu verstehen. Es bleibt aber die | understand the flow of the program but two questions remain: (i) How | ||||||
| Frage, wie man das Kontrollskript unter den anderen \codeterm{m-files} | to organize the files on the file system and (ii) how to name them | ||||||
| als solches erkennt. Um dieses zu erleichtern gilt es zwei Dinge zu | that the controlling script is easily identified among the other | ||||||
| beachten: (i) Wie werden Programme im Dateisystem organisiert? (ii) Wie | \codeterm{m-files}. | ||||||
| werden Programme benannt? |  | ||||||
| 
 | 
 | ||||||
| Es hilft ungemein, wenn zusammengeh\"orige Skripte und Funktionen im | Upon installation ``MATLAB'' creates a folder called \emph{MATLAB} in | ||||||
| gleichen Ordner auf der Festplatte zu finden sind. Es bietet sich also | the user space (Windows: My files, Linux: Documents, MacOS: | ||||||
| an, f\"ur jede Analyse einen eigenen Ordner anzulegen und in diesem | Documents). Since this folder is already appended to the Matlab search | ||||||
| die zugeh\"origen \codeterm{m-files} abzulegen. Auf eine tiefere | path (Box~\ref{matlabpathbox}), it is easiest to stick to it for the | ||||||
| Schachtelung in weitere Unterordner kann in der Regel verzichtet | moment. Of course, any other location can specified as well. Generally | ||||||
| werden. \matlab{} erzeugt einen ``MATLAB'' Ordner im eigenen | it is of great advantage to store related scripts and functions within | ||||||
| \file{Documents} (Linux) oder \file{Eigene Dokumente} (Windows) | the same folder on the hard drive. An easy approach is to create a | ||||||
| Ordner. Es bietet sich an, diesen Ordner als Wurzelverzeichnis f\"ur | project-specific folder structure that contains sub-folders for each | ||||||
| eigene Arbeiten zu verwenden. Nat\"urlich kann auch jeder andere Ort | task (analysis) and to store all related \codeterm{m-files} | ||||||
| gew\"ahlt werden. In dem Beispiel in \figref{fileorganizationfig} wird | (screenshot \ref{fileorganizationfig}). In these task-related folders | ||||||
| innerhalb dieses Ordners f\"ur jedes Projekt ein eigener Unterordner | one may consider to create a further sub-folder to store results | ||||||
| erstellt, in welchem wiederum f\"ur jedes Problem, jede Analyse ein | (created figures, result data). On the project level a single script | ||||||
| weiterer Unterodner erstellt wird. In diesen liegen sowohl die | (analysis.m) controls the whole process. In parallel to the project | ||||||
| ben\"otigten \codeterm{m-files} also auch die Resultate der Analyse | folder we suggest to create an additional folder for functions that | ||||||
| (Abbildungen, Daten-Dateien). Zu bemerken sind noch zwei weitere | are or may be relevant across different projects. | ||||||
| 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 | Within such a structure it is quite likely that programs in different | ||||||
| wahrscheinlich ist, dass bestimmte Namen f\"ur Funktionen und Skripte | projects share the same name (e.g. a ``load\_data.m'' | ||||||
| mehrfach verwendet werden. Es ist nicht verwunderlich, wenn eine | function). Usually this will not lead to conflicts due to the way | ||||||
| \file{load\_data.m} Funktion in jeder Analyse vorkommt. In der Regel | matlab searches for matching functions which always starts in the | ||||||
| wird dies nicht zu Konflikten f\"uhren, da \matlab{} zuerst im | current folder (more information on the \matlab-path in | ||||||
| aktuellen Ordner nach passenden Dateien sucht (mehr Information zum | Box~\ref{matlabpathbox}). | ||||||
| \matlab-Suchpfad in Box~\ref{matlabpathbox}). |  | ||||||
| 
 | 
 | ||||||
| \begin{figure}[tp] | \begin{figure}[tp] | ||||||
|   \includegraphics[width=0.75\textwidth]{program_organization} |   \includegraphics[width=0.75\textwidth]{program_organization} | ||||||
|   \titlecaption{\label{fileorganizationfig} M\"ogliche Organisation von |   \titlecaption{\label{fileorganizationfig} Possible folder structure | ||||||
|     Programmcode im Dateisystem.}{ F\"ur jedes Projekt werden |     for maintaining program code on the file system.}{For each project | ||||||
|     Unterordner f\"ur die einzelnen Analysen angelegt. Auf Ebene des |     one maintains an individual folder in which analyses or tasks may | ||||||
|     Projektes k\"onnte es ein Skript (hier ``analysis.m'') geben, |     be structured in sub-folders. Within each analysis a ``main.m'' | ||||||
|     welches alle Analysen in den Unterordnern anst\"o{\ss}t.} |     script is the entry point for the analyses. On the project level | ||||||
|  |     there could be a single script that triggers and controls all | ||||||
|  |     analyses and tasks in the sub-folders. Functions that are of | ||||||
|  |     general interest across projects are best kept in a dedicated | ||||||
|  |     folder outside the project sub-structure.} | ||||||
| \end{figure} | \end{figure} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| \begin{ibox}[tp]{\label{matlabpathbox}Der \matlab{} Suchpfad} | \begin{ibox}[tp]{\label{matlabpathbox}\matlab{} search path} | ||||||
|   Der Suchpfad definiert, wo \matlab{} nach Skripten und Funktionen |   The \codeterm{search path} defines where \matlab{} looks for scripts | ||||||
|   sucht. Wird eine Funktion aufgerufen wird zun\"achst im aktuellen |   and functions. When calling a function from the command line | ||||||
|   Arbeitsverzeichnis einem Treffer gesucht. Schl\"agt diese Suche |   \matlab{} needs to figure out which function is addressed and starts | ||||||
|   fehl, so arbeitet sich \matlab{} durch den \codeterm{Suchpfad} |   looking for it in the current path. If this fails it will crawl all | ||||||
|   (siehe Abbildung). Der \codeterm{Suchpfad} ist eine Liste von |   locations listed in the search path (see figure). The | ||||||
|   Ordnern in denen \matlab{} nach Funktionen und Skripten suchen |   \codeterm{search path} is basically a list of folders. \matlab{} | ||||||
|   soll. Die Suche nach der aufgerufenen Funktion wird dabei von oben |   will go through this list from front to end and the search will stop | ||||||
|   nach unten durchgef\"uhrt. Das heisst, dass es bei |   on the first match. This implies that the order in the search path | ||||||
|   Namensgleichheit eine Rolle spielen kann an welcher Stelle im |   may affect which version of functions that share the same name is | ||||||
|   Suchpfad der erste Treffer gefunden wird. Wichtig: \matlab{} sucht |   used. Note: \matlab{} does not perform a recursive search. That is, | ||||||
|   nicht rekursiv! Wenn die gew\"unschte Funktion in einem Unterordner |   a function that resides in a sub-folder that is not explicitly | ||||||
|   des aktuellen Arbeitsverzeichnisses liegt, dieses aber nicht |   listed in the \codeterm{search path} will not be found. | ||||||
|   explizit im Suchpfad enthalten ist, so wird die Funktion nicht |  | ||||||
|   gefunden. |  | ||||||
| 
 | 
 | ||||||
|   \vspace{2ex} |   \vspace{2ex} | ||||||
|   \includegraphics[width=0.9\textwidth]{search_path} |   \includegraphics[width=0.9\textwidth]{search_path} | ||||||
|   \vspace{1.5ex} |   \vspace{1.5ex} | ||||||
| 
 | 
 | ||||||
|   Der Suchpfad kann sowohl \"uber die Kommandozeile mit dem Kommandos |   The search path can be managed from the command line by using the | ||||||
|   \code{addpath()} und \code{userpath()} als auch\"uber die in der |   functions \code{addpath()} or \code{userpath()}. Alternatively, the | ||||||
|   Abbildung gezeigte GUI angezeigt und eingestellt werden. Die GUI |   \matlab{} UI offers a graphical tool for adding/removing paths, or | ||||||
|   erlaubt Ordner aus dem Suchpfad zu entfernen, neue Ordner (optional |   changing the order of entries. | ||||||
|   inklusive aller Unterordner) hinzuzuf\"ugen oder die Reihenfolge der |  | ||||||
|   Pfade zu ver\"andern. |  | ||||||
| 
 | 
 | ||||||
|   Zum Wechseln des aktuellen Arbeitsverzeichnisses wird das Kommando |   The current working directory can be changed via the UI or also the | ||||||
|   \code{cd} verwendet. \code{which} zeigt an, in welchem Pfad eine |   command line using the command \code{cd} (for change directory). The | ||||||
|   bestimmte Funktion gefunden wurde. Das aktuelle Areitsverzeichnis |   current path is shown in the current directory text field of the UI | ||||||
|   wird durch den Aufruf \code{pwd} auf der Kommandozeile ausgegeben. |   or can be requested using the command \code{pwd} (for present work | ||||||
|  |   directory). The function \code{which()} shows the full path of the | ||||||
|  |   actually used function. For example, finding out which \code{mean()} | ||||||
|  |   function is used gives a result similar to: | ||||||
|  |   \begin{lstlisting}[label=useofwhich, caption={Use of 'which'}] | ||||||
|  |     >> which('mean') | ||||||
|  |     /Applications/MATLAB2018b.app/toolbox/matlab/datafun/mean.m | ||||||
|  |   \end{lstlisting} | ||||||
| \end{ibox} | \end{ibox} | ||||||
| 
 | 
 | ||||||
| \section{Namensgebung von Funktionen und Skripten} | \section{Naming scripts and functions} | ||||||
|  | \matlab{} will search the search path (Box \ref{matlabpathbox}) | ||||||
|  | exclusively by name. It is case-sensitive this implies that the files | ||||||
|  | \file{test\_function.m} and \file{Test\_function.m} are two different | ||||||
|  | things. It is self-evident that choosing such names is nonsensical | ||||||
|  | because the name contains no cue about the difference between the two | ||||||
|  | and it further tells close to nothing about the purpose. Finding good | ||||||
|  | names is not trivial sometimes it is harder than the programming | ||||||
|  | itself. Expressive names, however, pay off! Expressive means that the | ||||||
|  | name provides information about the purpose. | ||||||
| 
 | 
 | ||||||
| \matlab{} sucht Funktionen und Skripte ausschlie{\ss}lich anhand des | \begin{important}[Naming scripts and functions] | ||||||
| Namens. Dabei spielt die Gro{\ss}- und Kleinschreibung eine Rolle. Die |   Function and script names should be expressive in the sense that the | ||||||
| beiden Dateien \file{test\_funktion.m} und \file{Test\_Funktion.m} |   name provides information about the function's purpose | ||||||
| zwei unterschiedliche Funktionen benennen k\"onnen. Diese Art der |   (\file{estimate\_firingrate.m} tells much more than | ||||||
| Variation des Namens ist nat\"urlich nicht sinnvoll. Sie tr\"agt keine |   \file{exercise1.m}). Choosing a good name replaces large parts of | ||||||
| Information \"uber den Unterschied der beiden Funktionen. Auch sagt |   the documentation. | ||||||
| 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} | \end{important} | ||||||
| 
 | 
 | ||||||
| In Namen verbietet \matlab{} verbietet Leerzeichen, Sonderzeichen und | \matlab{} has a few rules about names: Names must not start with a | ||||||
| Umlaute. Namen d\"urfen auch nicht mit Zahlen anfangen. Es mach f\"ur | number, they must not contain blanks or other special characters like | ||||||
| die Namensgebung selbst keine weiteren Vorgaben. Allerdings folgt die | e.g. German Umlauts. Otherwise one is free to use whatever suits. The | ||||||
| Benennung der in \matlab{} vordefinierten Funktionen gewissen Mustern: | names of pre-defined functions shipped with \matlab{} follows several | ||||||
|  | patterns: | ||||||
| \begin{itemize} | \begin{itemize} | ||||||
| \item Namen werden immer klein geschrieben. | \item Names are always lowercase. | ||||||
| \item Es werden gerne Abk\"urzungen eingesetzt (z.B. \code{xcorr()} | \item Names are often abbreviations (e.g. \code{xcorr()} | ||||||
|   f\"ur die Kreuzkorrelation oder \code{repmat()} f\"ur ``repeat matrix'') |   stands for cross-correlation \code{repmat()} for ``repeat matrix''). | ||||||
| \item Funktionen, die zwischen Formaten konvertieren sind immer nach | \item Functions that convert between formats are named according to | ||||||
|   dem Muster ``format2format'' (z.B. \code{num2str()} f\"ur die |   the pattern ``format2format'' (e.g. \code{num2str()} for ``number to string'' conversion). | ||||||
|   Konvertierung ``number to string'', Umwandlung eines numerischen |  | ||||||
|   Wertes in einen Text) benannt. |  | ||||||
| \end{itemize} | \end{itemize} | ||||||
| 
 | 
 | ||||||
| Andere \"ubliche Muster sind der \emph{camelCase}, bei dem die | There are other common patterns such as the \emph{camelCase} in which | ||||||
| Anf\"ange zusammengesetzter Worte jeweils gro{\ss} geschrieben werden | the first character of compound words is capitalized. Other | ||||||
| oder auch die Verwendung von Unterstrichen zur Trennung von | conventions use the underscore to separate the individual words | ||||||
| Namenskomponenten. Eine Funktion, die die Anzahl von | \emph{snake\_case}. A function that counts the number of action | ||||||
| Aktionspotentialen bestimmt k\"onnte etwa \file{spikeCount.m} oder | potentials could be named \file{spikeCount.m} or | ||||||
| \file{spike\_count.m} benannt werden. | \file{spike\_count.m}. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| \section{Namensgebung von Variablen und Konstanten} | \section{Naming variables and constants} | ||||||
| 
 | 
 | ||||||
| F\"ur die Bennennung von Variablen und Konstanten gelten die gleichen | \matlab{} applies the same rules for naming variables and constants as | ||||||
| Regeln wie f\"ur die Namen von Funktionen und Skripten. Die Maxime von | for the naming of scripts and functions. The dictum of good | ||||||
| gutem Programmierstil ist: \emph{``Programmcode muss lesbar | code style is: ``Program code must be readable.'' Expressive | ||||||
|   sein.''}. Dabei helfen gute Namen ungemein. Auch wenn es schwer | names are extraordinarily important in this respect. Even if it is | ||||||
| f\"allt passende und trotzdem nicht zu lange Namen zu finden, sollte | tricky to find expressive names that are not overly long, naming | ||||||
| einer gute Namensgebung sehr ernst genommen werden. | should be taken seriously. | ||||||
| 
 | 
 | ||||||
| W\"ahrend die Namen von Funktionen und Skripten ihren Zweck | While the names of scripts and functions describe the purpose, names | ||||||
| beschreiben, sollten die Namen von Variablen ihren Inhalt | of variables describe the stored content. A variable storing the | ||||||
| beschreiben. Eine Variable, die die mittlere Anzahl von | average number of actions potentials could be called | ||||||
| Aktionspotentialen speichert, k\"onnte also | \varcode{average\_spike\_count}. If this variable is meant to store | ||||||
| \varcode{average\_spike\_count} hei{\ss}en. Wenn die Variable nicht | multiple spike counts the plural form would be appropriate | ||||||
| nur einen sondern mehrere Werte aufnimmt, dann ist der Plural | (\varcode{average\_spike\_counts}). | ||||||
| angebracht (\varcode{average\_spike\_counts}). |  | ||||||
| 
 | 
 | ||||||
| Die Laufvariablen von \code{for}-Schleifen werden oft nur \varcode{i}, | The control variables used in the head of a \code{for} loop are often | ||||||
| \varcode{j} oder \varcode{k} benannt und sollten aber die einzige Ausnahme | simply named \varcode{i}, \varcode{j} or \varcode{k}. This kind-of | ||||||
| bzgl. ausdrucksstarker Namensgebung bleiben. | clashes with the previously made statements but since it is a very | ||||||
|  | common pattern the meaning of such variables in the context of the | ||||||
|  | loop is quite obvious. This should, however, be the only exception to | ||||||
|  | the general rule of expressive naming. | ||||||
| 
 | 
 | ||||||
| \begin{important}[Benennung von Variablen] | \begin{important}[Naming of variables] | ||||||
|   Die Namen von Variablen sollten m\"oglichst viel \"uber ihren Inhalt |   The names of variables should be expressive. That is, the name | ||||||
|   aussagen (\varcode{spike\_count} statt \varcode{x}). Gute Namen |   itself should tell about the content of the variable. The name | ||||||
|   f\"ur Variablen sind die beste Dokumentation. |   \varcode{spike\_count} tells much more about the stored information | ||||||
|  |   than \varcode{x}. Choosing a good variable name replaces additional | ||||||
|  |   comments. | ||||||
| \end{important} | \end{important} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| \section{Codestil} | \section{Code style} | ||||||
|  | Readability of program code depends strongly on whether or not a | ||||||
|  | consistent code style is applied. A program that is only randomly | ||||||
|  | indented or that contains lots of empty lines is very hard to read and | ||||||
|  | to comprehend. Even though the \matlab{} language (as many others) | ||||||
|  | does not enforce indentation, indentation is very powerful for | ||||||
|  | defining coherent blocks. The \matlab{} editor supports this by an | ||||||
|  | auto-indentation mechanism. A selected section of the code and be | ||||||
|  | automatically indented by pressing the \keycode{Ctrl-I} combination. | ||||||
| 
 | 
 | ||||||
| Die Lesbarkeit von Programmen wird sehr durch den Codestil | Interspersing empty lines is very helpful to separate regions in the | ||||||
| beeinflusst. Ein Programm, in dem z.B. Schleifenk\"orper nicht (oder | code that belong together. Too many empty lines, however lead to | ||||||
| zuf\"allig) einger\"uckt sind ist deutlich schwerer zu lesen und zu | hard-to-read code because it might require more space than a granted | ||||||
| verstehen, als eines, in dem eine konsistente Einr\"uckung vorgenommen | by the screen and thus takes overview. | ||||||
| wurde. Mit der Tastenkombination \keycode{Ctrl-I} (\keycode{Strg-I} |  | ||||||
| auf der deutschen Tastatur) kann ein markierter Bereich im \matlab{} |  | ||||||
| Editor automatisch richtig einger\"uckt werden. |  | ||||||
| 
 | 
 | ||||||
| Sparsam und konsistent eingef\"ugte einzelne Leerzeilen sind | The following two listings show basically the same implementation of a | ||||||
| hervorragend geeignet, um logische Abschnitte eines Programm zu | random walk once in a rather chaotic version (listing | ||||||
| trennen. Zu viele Leerzeilen haben den Nachteil, dass das Programm | \ref{chaoticcode}) then in cleaner way (listing \ref{cleancode}) | ||||||
| nicht mehr auf eine Seite passt und dadurch leichter der \"Uberblick |  | ||||||
| verlorgen geht. |  | ||||||
| 
 | 
 | ||||||
| Die beiden folgenden Listings \ref{chaoticcode} und \ref{cleancode} | \begin{lstlisting}[label=chaoticcode, caption={Chaotic implementation of the random-walk.}] | ||||||
| zeigen die Implementation des random-walk einmal eher chaotisch und | num_runs = 10; max_steps = 1000; | ||||||
| einmal aufger\"aumt und \"ubersichtlich. |  | ||||||
|   |  | ||||||
| \begin{lstlisting}[label=chaoticcode, caption={Un\"ubersichtliche Implementation des Random-walk.}] |  | ||||||
| num_runs = 10; |  | ||||||
| max_steps = 1000; |  | ||||||
| 
 | 
 | ||||||
| positions = zeros(max_steps, num_runs); | positions = zeros(max_steps, num_runs); | ||||||
| 
 | 
 | ||||||
| @ -232,7 +225,7 @@ end | |||||||
| 
 | 
 | ||||||
| \pagebreak[4] | \pagebreak[4] | ||||||
| 
 | 
 | ||||||
| \begin{lstlisting}[label=cleancode, caption={\"Ubersichtliche Implementation des Random-walk.}] | \begin{lstlisting}[label=cleancode, caption={Clean implementation of the random-walk.}] | ||||||
| num_runs = 10; | num_runs = 10; | ||||||
| max_steps = 1000; | max_steps = 1000; | ||||||
| positions = zeros(max_steps, num_runs); | positions = zeros(max_steps, num_runs); | ||||||
| @ -249,33 +242,30 @@ for run = 1:num_runs | |||||||
| end | end | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \section{Verwendung von Kommentaren} | \section{Using comments} | ||||||
| 
 | 
 | ||||||
| Kommentarzeilen werden in \matlab{} mit dem Prozentzeichen \code{\%} | It is common to provide extra information about the meaning of program | ||||||
| gekennzeichnet.  Gezielt und sparsam eingesetzte Kommentare sind f\"ur | code by adding comments to it. In \matlab{} comments are indicated by | ||||||
| das Verst\"andnis eines Programms sehr n\"utzlich.  Am wichtigsten | the percent character \code{\%}. Anything that is written in the | ||||||
| sind kurze Kommentare, die den Zweck und das Ziel eines Abschnitts im | respective line following the percent is ignored and considered a | ||||||
| Programm erl\"autern (z.B. \varcode{\% compute mean firing rate over all | comment. When used sparsely comments can immensely important for | ||||||
|   trials}). | understanding. Comments are short sentences that describe the meaning | ||||||
|  | of the (following) lines in the program code. During the initial | ||||||
|  | implementation of a function they can be used to guide the development | ||||||
|  | but have the tendency to blow up the code and decrease readability. By | ||||||
|  | choosing expressive variable and function names, most lines should be | ||||||
|  | self-explanatory. | ||||||
| 
 | 
 | ||||||
| Viele und h\"aufige Kommentare k\"onnen in der Entwicklungsphase eines | For example stating the obvious does not really help:\\ | ||||||
| Programms sehr hilfreich sein, bl\"ahen aber den Code auf. Durch die |  | ||||||
| Verwendung guter Variablen- und Funktionsnamen sollten die meisten |  | ||||||
| Zeilen sowieso weitestgehend selbsterkl\"arend sein. |  | ||||||
| 
 |  | ||||||
| Die beste Dokumentation ist der Code selbst. Gut geschriebener Code |  | ||||||
| mit ausdrucksstarken Variablen- und Funktionsnamen ben\"otigt keine |  | ||||||
| Kommentare, um den Zweck einzelner Zeilen zu erkl\"aren. z.B. ist\\ |  | ||||||
| \varcode{ x = x + 2;   \% add two to x}\\ | \varcode{ x = x + 2;   \% add two to x}\\ | ||||||
| ein v\"ollig unn\"otiger Kommentar. |  | ||||||
| 
 | 
 | ||||||
| \begin{important}[Verwendung von Kommentaren] | \begin{important}[Using comments] | ||||||
|   \begin{itemize} |   \begin{itemize} | ||||||
|   \item Kommentare sollen die Absicht eines Programmabschnitts beschreiben. |   \item Comments describe the rationale of the respective code block. | ||||||
|   \item Kommentare sind gut und wichtig --- sie m\"ussen aber richtig |   \item Comments are good and helpful --- they have to be true, however! | ||||||
|     sein! |   \item A wrong comment is worse than a non-existent comment! | ||||||
|   \item Ein falscher Kommentar ist schlimmer als gar kein Kommentar! |   \item Comments must be maintained just as the code. Otherwise they | ||||||
|   \item Kommentare m\"ussen gepflegt werden, sonst sind sie wertlos! |     may become wrong and worse than meaningless! | ||||||
|   \end{itemize} |   \end{itemize} | ||||||
|   \widequote{Good code is its own best documentation. As you're about to add |   \widequote{Good code is its own best documentation. As you're about to add | ||||||
|     a comment, ask yourself, ``How can I improve the code so that this |     a comment, ask yourself, ``How can I improve the code so that this | ||||||
| @ -284,153 +274,139 @@ ein v\"ollig unn\"otiger Kommentar. | |||||||
| \end{important} | \end{important} | ||||||
| 
 | 
 | ||||||
| \pagebreak[4] | \pagebreak[4] | ||||||
| \section{Dokumentation von Funktionen} | \section{Documenting functions} | ||||||
|  | All pre-defined \matlab{} functions begin with a comment block that | ||||||
|  | describes the purpose of the function, the required and optional | ||||||
|  | arguments, and the values returned by the function. Using the | ||||||
|  | \code{help} command one can display these comments and learn how to | ||||||
|  | use the function properly. Self-written functions can and should be | ||||||
|  | documented in a similar way. Listing ~\ref{localfunctions} shows a | ||||||
|  | well documented function. | ||||||
| 
 | 
 | ||||||
| Bei allen vordefinierten \matlab{} Funktionen findet sich am Anfang | \begin{important}[Documenting functions] | ||||||
| eine Kommentarblock, der den Zweck der Funktion, die verschiedenen |   Functions must be properly documented, otherwise a user (the author | ||||||
| M\"oglichkeiten des Funktionsaufrufs und die Argumente und |   him- or herself) must read and understand the function code which is | ||||||
| R\"uckgabewerte beschreibt. Mit dem \code{help}- Befehl wird dieser |   a waste of time! | ||||||
| Kommentarblock angezeigt. Auch in eigenen Funktionen sind |  | ||||||
| diese Kommentare sehr wichtig. Siehe Listing~\ref{localfunctions} |  | ||||||
| f\"ur ein Beispiel einer gut dokumentierten Funktion. |  | ||||||
| 
 |  | ||||||
| \begin{important}[Dokumentation von Funktionen] |  | ||||||
|   Funktionen m\"ussen unbedingt kommentiert werde! |  | ||||||
|   \begin{itemize} |   \begin{itemize} | ||||||
|   \item In wenigen Zeilen kurz den Zweck der Funktion beschreiben. |   \item Describe with a few sentences the purpose of the function. | ||||||
|   \item Den Funktionskopf nocheinmal hinschreiben, damit |   \item Note the function head to illustrate the order of the argments. | ||||||
|     klar ist, in welcher Reihenfolge Argumente \"ubergeben werden. |   \item For each argument state the purpose, the expected data type | ||||||
|   \item F\"ur jedes Funktionsargument die Bedeutung, der erwartete |     (number, vector, matrix, etc.) and, if applicable, the unit in | ||||||
|     Datentyp (Zahl, Vektor, Matrix, etc.), und eventuell die Einheit, |     which a provided number must be given (e.g. seconds if a time is | ||||||
|     in der die Zahlen erwartet werden (z.B. Sekunden). |     expected). | ||||||
|   \item Ebenso m\"ussen die R\"uckgabewerte beschrieben werden. |   \item The same for all return values. | ||||||
|   \end{itemize} |   \end{itemize} | ||||||
| \end{important} | \end{important} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| \section{Auslagerung von Aufgaben in Funktionen} | \section{Delegating tasks in functions} | ||||||
|  | Comments and empty lines are used to organize code into logical blocks | ||||||
|  | and to briefly explain what they do. Whenever one feels tempted to do | ||||||
|  | this, one could also consider to delegate the respective task to a | ||||||
|  | function. In most cases this is preferable.  | ||||||
| 
 | 
 | ||||||
| Kommentare oder Leerzeilen werden benutzt, um logische Abschnitte des | Not delegating the tasks leads to very long \codeterm{m-files} which | ||||||
| Codes abzutrennen und kurz zu erkl\"aren. Wenn eine | can be confusing. Sometimes such a code is called ``spaghetti | ||||||
| solche inhaltliche Trennung einzuf\"ugt wird, sollte man sich immer fragen, | code''. It is high time to think about delegation of tasks to | ||||||
| ob dieser Teil des Programms nicht in eine eigene Funktion ausgelagert | functions. | ||||||
| werden sollte. Fast immer kann dies bejaht werden. |  | ||||||
| 
 | 
 | ||||||
| Abschnitte nicht auszulagern f\"uhrt zu sehr langen | \begin{important}[Delegating to functions] | ||||||
| \codeterm{m-files}, die leicht un\"ubersichtlich werden. Diese Art von |   When should one consider delegating tasks to specific functions? | ||||||
| Code wird \codeterm{Spaghetticode} genannt. Es ist h\"ochste Zeit |  | ||||||
| \"uber Auslagerung in Funktionen nachzudenken. |  | ||||||
| 
 |  | ||||||
| \begin{important}[Gliederung in Funktionen] |  | ||||||
|   Wann sollten Programmteile in eigene Funktionen ausgelagert werden? |  | ||||||
|   \begin{itemize} |   \begin{itemize} | ||||||
|   \item Wenn innerhalb einer Funktion oder eines Skripts mehr als zwei |   \item Whenever one needs more than two indentation levels to | ||||||
|     Einr\"uckungsebenen gebraucht werden. |     organize to code. | ||||||
|   \item Wenn sich Strukturen im Code mehr als einmal wiederholten. |   \item Whenever the same lines of code are repeated more than once. | ||||||
|   \item Wenn man versucht ist, wiederholte Strukturen  mit Copy and Paste zu erzeugen. |   \item Whenever one is tempted to use copy-and-paste. | ||||||
|   \end{itemize} |   \end{itemize} | ||||||
| \end{important} | \end{important} | ||||||
| 
 | 
 | ||||||
| \subsection{Lokale Funktionen und geschachtelte Funktionen} | \subsection{Local and nested functions} | ||||||
|  | Generally, functions live in their own \codeterm{m-files} that have | ||||||
|  | the same name as the function itself. Delegating tasks to functions | ||||||
|  | thus leads to a large set of \codeterm{m-files} which increases | ||||||
|  | complexity and may lead to confusion. If the delegated functionality | ||||||
|  | is used in multiple instances, it is advisable to do so. On the other | ||||||
|  | hand, when the delegated functionality is only used within the context | ||||||
|  | of another function \matlab{} allows to define | ||||||
|  | \codeterm[function!local]{local functions} and | ||||||
|  | \codeterm[function!nested]{nested functions} within the same | ||||||
|  | file. Listing \ref{localfunctions} shows an example of a local | ||||||
|  | function definition. | ||||||
| 
 | 
 | ||||||
| Das Auslagern von Funktionalit\"at in eigene Funktionen f\"uhrt dazu, | \pagebreak[3] \lstinputlisting[label=localfunctions, caption={Example | ||||||
| dass eine F\"ulle von Dateien erzeugt wird, die die |     for local functions.}]{calculateSines.m} | ||||||
| \"Ubersichtlichkeit nicht unbedingt erh\"oht. Wenn die auszulagernde |  | ||||||
| Funktionalit\"at an vielen Stellen ben\"otigt wird ist es dennoch sehr |  | ||||||
| sinnvoll dies zu tun. Wenn Funktionen nur von einzelnen anderen |  | ||||||
| Funktionen verwendet werden, dann bietet \matlab{} die M\"oglichkeit |  | ||||||
| sogenannte \codeterm[Funktion!lokale]{lokale Funktionen} oder auch |  | ||||||
| \codeterm[Funktion!geschachtelte]{geschachtelte Funktionen} |  | ||||||
| (\enterm{nested functions}) in einer einzelnen Datei zu |  | ||||||
| erstellen. Listing \ref{localfunctions} zeigt ein Beispiel f\"ur eine |  | ||||||
| lokale Funktion. |  | ||||||
| 
 | 
 | ||||||
| \pagebreak[3] | Local function live in the same \codeterm{m-file} as the main function | ||||||
| \lstinputlisting[label=localfunctions, caption={Beispiel f\"ur den | and are only available in this context. Each local function has its | ||||||
|   Einsatz von lokalen Funktionen.}]{calculateSines.m} | own \codeterm{scope}, that is, the local function can not access (read | ||||||
|  | or write) variables of the calling function. | ||||||
| 
 | 
 | ||||||
| Lokale Funktionen existieren in der gleichen Datei und sind nur dort | This is different in so called \codeterm[function!nested]{nested | ||||||
| verf\"ugbar. Jede Funktion hat ihren eigenen G\"ultigkeitsbereich, das |   functions}. These are defined within the body of the parent function | ||||||
| hei{\ss}t, dass Variablen aus den aufrufenden Funktionen nicht | (between the keywords \code{function} and \code{end}) and have full | ||||||
| sichtbar sind.  | access to all variables defined in the parent function. Working (in | ||||||
| 
 | particular changing) the parent's variables is handy on the one side, | ||||||
| Bei sogenannten \codeterm[Funktion!geschachtelte]{geschachtelten | but is also risky. One should take care when defining nested functions. | ||||||
| Funktionen} ist das anders. Diese werden innerhalb eines |  | ||||||
| Funktionsk\"orpers (zwischen den Schl\"usselworten \code{function} und |  | ||||||
| dem \code{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{Specifics when using scripts} | ||||||
|  | A similar problem as with nested function arises when using scripts | ||||||
|  | (instead of functions). All variables that are defined within a script | ||||||
|  | become available in the global \codeterm{Workspace}. There is the risk | ||||||
|  | of name conflicts, that is, a called sub-script redefines or uses the | ||||||
|  | same variable name and may \emph{silently} change its content. The | ||||||
|  | user will not be notified by this change and the calling script may | ||||||
|  | expect a completely different content. Bugs that are based on such | ||||||
|  | mistakes are hard to find since the program itself looks perfectly | ||||||
|  | fine. | ||||||
| 
 | 
 | ||||||
| Ein \"ahnliches Problem wurde schon bei der Einf\"uhrung der Skripte | To avoid such issues one should design scripts in a way that they | ||||||
| erw\"ahnt. Variablen, die in Skripten definiert werden sind global im | perform their tasks independent from other scripts and functions. | ||||||
| \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. |  | ||||||
| 
 | 
 | ||||||
| Um dieses Problem zu vermeiden sollten Skripte genauso wie Funktionen | A common use case for a script could be to control the analyses made | ||||||
| eine spezifische Aufgabe unabh\"angig vom Kontext erf\"ullen. Diese | on many datasets and to collect the results. A good script is still | ||||||
| Aufgabe ist dann nat\"urlich komplexer als die einer | not too long and is thus easy to comprehend.  Another advantage of | ||||||
| Funktion. z.B. k\"onnte die Aufgabe eines Skriptes sein, die | small task-related scripts is that they can be directly executed by | ||||||
| Spiketrains aller aufgenommenen Zellen zu analysieren. Gute Skripte | either calling them from the command line or pressing \keycode{F5} in | ||||||
| sind trotzdem nicht \"uberm\"a{\ss}ig lang und deshalb leicht zu | the editor. Should it fail there will be a proper error message that | ||||||
| verstehen. | provides important information to track and fix the bug. | ||||||
| 
 | 
 | ||||||
| Ein weiterer, sehr wichtiger Vorteil von zweckbestimmten Skripten ist, | \begin{important}[Structuring scripts] | ||||||
| dass sie immer als ganzes ausf\"uhrbar sind --- am einfachsten mit |  | ||||||
| \keycode{F5} aus dem \matlab-Editor heraus. Wenn ein Fehler auftritt |  | ||||||
| ist in der Fehlermeldung die Zeilennummer des fehlerhaften Codes |  | ||||||
| angegeben. Das ist eine sehr wichtige Information, um den Fehler |  | ||||||
| beheben zu k\"onnen. |  | ||||||
| 
 |  | ||||||
| \"Ubergeordnete Skripte k\"onnen dann einfach nacheinander |  | ||||||
| spezifischere Skripte aufrufen. Durch die Namen der aufgerufenen |  | ||||||
| Skripte ist dann klar, was passieren wird, und durch die |  | ||||||
| Unabh\"angigkeit der Skripte kommt es nicht zu Kollisionen. |  | ||||||
| 
 |  | ||||||
| \begin{important}[Struktur von Skripten] |  | ||||||
|   \begin{itemize} |   \begin{itemize} | ||||||
|   \item Skripte sollten genauso wie Funktionen spezifische Aufgaben |   \item Similar to functions script should solve one task and should | ||||||
|     l\"osen und nicht zu lang sein. |     not be too long. | ||||||
| 
 | 
 | ||||||
|   \item Skripte sollten unabh\"angig von irgendwelchen Variablen im |   \item Scripts should work independently of existing variables in the | ||||||
|     \codeterm{Workspace} f\"ur sich alleine geschlossen lauff\"ahig |     global workspace. | ||||||
|     sein. |  | ||||||
|      |  | ||||||
|   \item Es empfiehlt sich zu Beginn eines Skriptes alle Variablen im |  | ||||||
|     \codeterm{Workspace} zu l\"oschen (\code{clear}). Meist ist auch |  | ||||||
|     ein \code{close all}, um alle Figures zu schlie{\ss}en, |  | ||||||
|     angebracht. |  | ||||||
| 
 | 
 | ||||||
|   \item Am Ende eines Skriptes sollte der \codeterm{Workspace} |   \item It is advisable to start a script with deleting variables | ||||||
|     mithilfe von \code{clear} wieder von all den Variablen ges\"aubert |     (\code{clear}) from the workspace and most of the times it is also | ||||||
|     werden, die nicht mehr ben\"otigt werden. |     good to close all open figures (\code{close all}). | ||||||
|  | 
 | ||||||
|  |   \item Clean up the workspace at the end of a script. Delete | ||||||
|  |     (\code{clear}) all variables that are no longer needed. | ||||||
|   \end{itemize} |   \end{itemize} | ||||||
| \end{important} | \end{important} | ||||||
| 
 | 
 | ||||||
| \section{Fazit} |  | ||||||
| 
 | 
 | ||||||
| Programmcode soll lesbar sein. Namen von Variablen, Funktionen und | \section{Summary} | ||||||
| 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 | Program code must be readable. Names of variables, functions and | ||||||
| werden. Wenn diese nicht von globalem Interesse sind, kann mit | scripts should be expressive and describe their purpose (scripts and | ||||||
| \codeterm[Funktion!lokale]{lokalen} oder | functions) or their content (variables). Cultivating a personalized | ||||||
| \codeterm[Funktion!geschachtelte]{geschachtelten | code style is perfectly fine as long as it is consistent. Many | ||||||
|   Funktionen} die \"Ubersichtlichkeit erh\"oht werden. | programming languages or communities have their own traditions. It is | ||||||
|  | advisable to adhere to these. | ||||||
| 
 | 
 | ||||||
| Es lohnt sich auf den eigenen Programmierstil zu | Repeated tasks should (to be read as must) be delegated to | ||||||
| achten!\footnote{Buchtip: Robert C. Martin: \textit{Clean Code: A | functions. In cases in which a function is only locally applied and | ||||||
|     Handbook of Agile Software Craftmanship}, Prentice Hall} | not of more global interest across projects consider to define it as | ||||||
|  | \codeterm[function!local]{local function} or | ||||||
|  | \codeterm[function!nested]{nested function}. Taking care to increase | ||||||
|  | readability and comprehensibility pays off, even to the author! | ||||||
|  | 
 | ||||||
|  | \footnote{Reading tip: Robert C. Martin: \textit{Clean Code: A Handbook of | ||||||
|  |     Agile Software Craftmanship}, Prentice Hall} | ||||||
| 
 | 
 | ||||||
| \shortquote{Programs must be written for people to read, and only | \shortquote{Programs must be written for people to read, and only | ||||||
|   incidentally for machines to execute.}{Abelson / Sussman} |   incidentally for machines to execute.}{Abelson / Sussman} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user