diff --git a/Makefile b/Makefile index 1fcb26f..2038f42 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BASENAME=scientificcomputing-script -SUBDIRS=programming plotting statistics bootstrap regression likelihood pointprocesses designpattern +SUBDIRS=programming plotting programmingstyle statistics bootstrap regression likelihood pointprocesses designpattern SUBTEXS=$(foreach subd, $(SUBDIRS), $(subd)/lecture/$(subd).tex) pdf : chapters $(BASENAME).pdf diff --git a/header.tex b/header.tex index 4423fdc..aeda8d4 100644 --- a/header.tex +++ b/header.tex @@ -171,6 +171,7 @@ \newcommand{\enterm}[1]{``#1''} \newcommand{\determ}[1]{\textit{#1}} \newcommand{\codeterm}[1]{\textit{#1}} +\newcommand{\keycode}[1]{\texttt{#1}} \newcommand{\file}[1]{\texttt{#1}} %%%%% code/matlab commands: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/programmingstyle/code/calculate_sines.m b/programmingstyle/code/calculate_sines.m new file mode 100644 index 0000000..05ad1ca --- /dev/null +++ b/programmingstyle/code/calculate_sines.m @@ -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 diff --git a/programmingstyle/lecture/Makefile b/programmingstyle/lecture/Makefile new file mode 100644 index 0000000..ad1b36a --- /dev/null +++ b/programmingstyle/lecture/Makefile @@ -0,0 +1,31 @@ +BASENAME=programmingstyle + +#TEXFILES=programmingstyle.tex + +PYFILES=$(wildcard *.py) +PYPDFFILES=$(PYFILES:.py=.pdf) + +all : pdf + +# script: +pdf : $(BASENAME)-chapter.pdf + +$(BASENAME)-chapter.pdf : $(BASENAME)-chapter.tex $(BASENAME).tex $(PYPDFFILES) ../../header.tex + pdflatex -interaction=scrollmode $< | tee /dev/stderr | fgrep -q "Rerun to get cross-references right" && pdflatex -interaction=scrollmode $< || true + +$(PYPDFFILES) : %.pdf : %.py + python $< + +clean : + rm -f *~ + rm -f $(BASENAME).aux $(BASENAME).log + rm -f $(BASENAME)-chapter.aux $(BASENAME)-chapter.log $(BASENAME)-chapter.out + rm -f $(PYPDFFILES) $(GPTTEXFILES) + +cleanall : clean + rm -f $(BASENAME)-chapter.pdf + +watchpdf : + while true; do ! make -q pdf && make pdf; sleep 0.5; done + + diff --git a/programmingstyle/lecture/beamercolorthemetuebingen.sty b/programmingstyle/lecture/beamercolorthemetuebingen.sty new file mode 100644 index 0000000..c4a5da6 --- /dev/null +++ b/programmingstyle/lecture/beamercolorthemetuebingen.sty @@ -0,0 +1,61 @@ +% Copyright 2007 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/licenses/LICENSE for more details. + +\usepackage{color} +\definecolor{karminrot}{RGB}{165,30,55} +\definecolor{gold}{RGB}{180,160,105} +\definecolor{anthrazit}{RGB}{50 ,65 ,75 } + +\mode + +\setbeamercolor*{normal text}{fg=anthrazit,bg=white} +\setbeamercolor*{alerted text}{fg=anthrazit} +\setbeamercolor*{example text}{fg=anthrazit} +\setbeamercolor*{structure}{fg=gold,bg=karminrot} + +\providecommand*{\beamer@bftext@only}{% + \relax + \ifmmode + \expandafter\beamer@bftext@warning + \else + \expandafter\bfseries + \fi +} +\providecommand*{\beamer@bftext@warning}{% + \ClassWarning{beamer} + {Cannot use bold for alerted text in math mode}% +} + +\setbeamerfont{alerted text}{series=\beamer@bftext@only} + +\setbeamercolor{palette primary}{fg=karminrot,bg=white} +\setbeamercolor{palette secondary}{fg=gold,bg=white} +\setbeamercolor{palette tertiary}{fg=anthrazit,bg=white} +\setbeamercolor{palette quaternary}{fg=black,bg=white} + +\setbeamercolor{sidebar}{bg=karminrot!100} + +\setbeamercolor{palette sidebar primary}{fg=karminrot} +\setbeamercolor{palette sidebar secondary}{fg=karminrot} +\setbeamercolor{palette sidebar tertiary}{fg=karminrot} +\setbeamercolor{palette sidebar quaternary}{fg=karminrot} + +\setbeamercolor{item projected}{fg=black,bg=black!20} + +\setbeamercolor*{block body}{} +\setbeamercolor*{block body alerted}{} +\setbeamercolor*{block body example}{} +\setbeamercolor*{block title}{parent=structure} +\setbeamercolor*{block title alerted}{parent=alerted text} +\setbeamercolor*{block title example}{parent=example text} + +\setbeamercolor*{titlelike}{parent=structure} + +\mode + diff --git a/programmingstyle/lecture/figures/program_organization.png b/programmingstyle/lecture/figures/program_organization.png new file mode 100644 index 0000000..56a7a98 Binary files /dev/null and b/programmingstyle/lecture/figures/program_organization.png differ diff --git a/programmingstyle/lecture/figures/search_path.png b/programmingstyle/lecture/figures/search_path.png new file mode 100644 index 0000000..d78192f Binary files /dev/null and b/programmingstyle/lecture/figures/search_path.png differ diff --git a/programmingstyle/lecture/programmingstyle-chapter.tex b/programmingstyle/lecture/programmingstyle-chapter.tex new file mode 100644 index 0000000..fffe3a4 --- /dev/null +++ b/programmingstyle/lecture/programmingstyle-chapter.tex @@ -0,0 +1,17 @@ +\documentclass[12pt]{report} + +\input{../../header} + +\lstset{inputpath=../code} + +\graphicspath{{figures/}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\include{programmingstyle} + +\end{document} + diff --git a/programmingstyle/lecture/programmingstyle.tex b/programmingstyle/lecture/programmingstyle.tex new file mode 100644 index 0000000..0807c9d --- /dev/null +++ b/programmingstyle/lecture/programmingstyle.tex @@ -0,0 +1,378 @@ +\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 aber in erster Linie +f\"ur den Verfasser 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 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{Organisation von m-Files im Dateisystem} + +In der Einf\"uhrung zu Funktionen und Skripten wurde schon einmal ein +typisches Programmlayout vorgestellt (\figref{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: (i) Wie werden Programme im Dateisystem organisiert? (ii) 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 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]{program_organization} + \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 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 des +Namens. Dabei spielt die Gro{\ss}- und Kleinschreibung eine Rolle. Das +hei{\ss}t, dass 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 ein R\"uckschluss auf den Zweck ziehen lassen sollte. + +\begin{important} + Die Namen von Funktionen und Skripte 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} + +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 von +Aktionspotentialen bestimmt k\"onnte etwa \file{spikeCount.m} oder +\file{spike\_count.m} benannt werden. + + +\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 und nicht zu lange Namen zu finden, sollte einer gute +Namensgebung ernst genommen werden. + +W\"ahrend die Namen von Funktionen und Skripten ihren Zweck +beschreiben, sollten die Namen von Variablen ihren Inhalt +beschreiben. Eine Variable, die die mittlere Anzahl von +Aktionspotentialen 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}). + +Die Laufvariablen von \code{for}-Schleifen werden oft nur \code{i}, +\code{j} oder \code{k} benannt und sollten aber die einzige Ausnahme +bzgl. ausdrucksstarker Namensgebung bleiben. + +\begin{important} + Die Namen von Variablen sollten m\"oglichst viel \"uber ihren Inhalt + aussagen (\code{spike\_count} statt \code{x}). Gute Namen + f\"ur Variablen sind die beste Dokumentation. +\end{important} + + +\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. 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 +hervorragend geeignet, um logische Abschnitte eines Programm zu +trennen. Zu viele Leerzeilen haben den Nachteil, dass das Programm +nicht mehr auf eine Seite passt und dadurch leichter der \"Uberblick +verlorgen geht. + +Die beiden folgenden Listings \ref{chaoticcode} und \ref{cleancode} +zeigen die Implementation des random-walk einmal eher chaotisch und +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); + +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} + +\clearpage + +\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} + +\section{Verwendung von Kommentaren} + +Kommentarzeilen werden in \matlab{} mit dem Prozentzeichen \cide{\%} +gekennzeichnet. Gezielt und sparsam eingesetzte Kommentare sind f\"ur +das Verst\"andnis eines Programms sehr n\"utzlich. Am wichtigsten +sind kurze Kommentare, die den Zweck und das Ziel eines Abschnitts im +Programm erl\"autern (z.B. \code{\% compute mean firing rate over all + trials}). + +Viele und h\"aufige Kommentare k\"onnen in der Entwicklungsphase eines +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\\ +\code{ x = x + 2; \% add two to x}\\ +ein v\"ollig unn\"otiger Kommentar. + +\begin{important} + \begin{itemize} + \item Kommentare sollen die Absicht eines Programmabschnitts beschreiben. + \item Kommentare sind gut und wichtig --- sie m\"ussen aber richtig + sein! + \item Ein falscher Kommentar ist schlimmer als gar kein Kommentar! + \item Kommentare m\"ussen gepflegt werden, sonst sind sie wertlos! + \end{itemize} +\end{important} + +\section{Dokumentation von Funktionen} + +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 sind diese +Kommentare sehr hilfreich. Siehe Listing~\ref{localfunctions} f\"ur +ein Beispiel einer gut Dokumentierten Funktion. + +\begin{important} + Funktionen m\"ussen unbedingt kommentiert werde! + \begin{itemize} + \item In wenigen Zeilen kurz den Zweck der Funktion beschreiben. + \item F\"ur jedes Funktionsargument die Bedeutung, der erwartete + Datentyp (Zahl, Vektor, Matrix, etc.), und eventuell die Einheit, + in der die Zahlen erwartet werden (z.B. Sekunden). + \item Ebenso m\"ussen die R\"uckgabewerte beschrieben werden. + \end{itemize} +\end{important} + + +\section{Auslagerung von Aufgaben in Funktionen} + +Kommentare oder Leerzeilen werden benutzt, um logische Abschnitte des +Codes abzutrennen und kurz zu erkl\"aren. Wenn eine +solche inhaltliche Trennung einzuf\"ugt wird, sollte man sich immer fragen, +ob dieser Teil des Programms nicht in eine eigene Funktion ausgelagert +werden sollte. Fast immer kann dies bejaht werden. + +Abschnitte nicht auszulagern f\"uhrt zu sehr langen +\codeterm{m-Files}, die leicht un\"ubersichtlich werden. Diese Art von +Code wird \codeterm{Spaghetticode} genannt. Es ist h\"ochste Zeit +\"uber Auslagerung in Funktionen nachzudenken. + +\begin{important} + Wann sollten Programmteile in eigene Funktionen ausgelagert werden? + \begin{itemize} + \item Wenn innerhalb einer Funktion oder eines Skripts mehr als zwei + Einr\"uckungsebenen gebraucht werden. + \item Wenn sich Strukturen im Code mehr als einmal wiederholten. + \item Wenn man versucht ist, wiederholte Strukturen mit Copy and Paste zu erzeugen. + \end{itemize} +\end{important} + +\subsection{Lokale Funktionen und geschachtelte Funktionen} + +Das Auslagern von Funktionalit\"at in eigene Funktionen f\"uhrt +dazu, dass eine F\"ulle von Dateien erzeugt wird, die die +\"Ubersichtlichkeit nicht unbedingt erh\"oht. Wenn die auszulagernde +Funktionalit\"at an vielen Stellen ben\"otigt wird ist es +dennoch sinnvoll 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. + + +\section{Besonderheiten bei Skripten} + +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} + 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. + + 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 nicht von globalem Interesse sind, kann mit +\codeterm{lokalen} oder \codeterm{geschachtelten Funktionen} die +\"Ubersichtlichkeit erh\"oht werden. + +\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} diff --git a/scientificcomputing-script.tex b/scientificcomputing-script.tex index fe5ac4e..7d0503f 100644 --- a/scientificcomputing-script.tex +++ b/scientificcomputing-script.tex @@ -27,6 +27,11 @@ \lstset{inputpath=plotting/code/} \include{plotting/lecture/plotting} + +\graphicspath{{programmingstyle/lecture/}{programmingstyle/lecture/figures/}} +\lstset{inputpath=programmingstyle/code/} +\include{programmingstyle/lecture/programmingstyle} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \part{Grundlagen der Datenanalyse}