Zentral makefile include for chapters of script

This commit is contained in:
2015-11-28 12:16:53 +01:00
parent 7719cb3385
commit 3e0f8c10a1
28 changed files with 236 additions and 333 deletions

View File

@@ -1,32 +1,12 @@
BASENAME=programmingstyle
PYFILES=$(wildcard *.py)
PYPDFFILES=$(PYFILES:.py=.pdf)
all : pdf
include ../../chapter.mk
# script:
pdf : $(BASENAME)-chapter.pdf
$(BASENAME)-chapter.pdf : $(BASENAME)-chapter.tex $(BASENAME).tex $(PYPDFFILES) ../../header.tex
CHAPTER=$$(( $$(sed -n -e '/contentsline {chapter}/{s/.*numberline {\([0123456789]*\)}.*/\1/; p}' $(BASENAME).aux) - 1 )); \
PAGE=$$(sed -n -e '/contentsline {chapter}/{s/.*numberline {.*}.*}{\(.*\)}{chapter.*/\1/; p}' $(BASENAME).aux); \
sed -i -e "s/setcounter{page}{.*}/setcounter{page}{$$PAGE}/; s/setcounter{chapter}{.*}/setcounter{chapter}{$$CHAPTER}/" $(BASENAME)-chapter.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
pdf : chapter
clean : cleanchapter
cleanall : clean cleanchapter

View File

@@ -5,8 +5,10 @@
\lstset{inputpath=../code}
\graphicspath{{figures/}}
\setcounter{page}{45}
\setcounter{chapter}{2}
\typein[\pagenumber]{Number of first page}
\typein[\chapternumber]{Chapter number}
\setcounter{page}{\pagenumber}
\setcounter{chapter}{\chapternumber}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@@ -6,14 +6,16 @@ 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.
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}
\item Die Struktur von Programmen.
\item Die Dateistruktur 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
@@ -65,7 +67,7 @@ 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}
\includegraphics[width=0.82\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
@@ -82,46 +84,45 @@ aktuellen Ordner nach passenden Dateien sucht (mehr Information zum
(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
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.
gefunden.
\vspace{2ex}
\includegraphics[width=0.75\textwidth]{search_path}
\includegraphics[width=0.9\textwidth]{search_path}
\vspace{1.5ex}
Der Suchpfad kann sowohl \"uber die in der Abbildung gezeigte GUI
oder auch \"uber die Kommandozeile 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.
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 aktuelle Arbeitsverzeichnis wechseln 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.
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. 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.
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 ein R\"uckschluss auf den Zweck ziehen lassen sollte.
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
@@ -158,8 +159,8 @@ 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.
f\"allt passende und trotzdem nicht zu lange Namen zu finden, sollte
einer gute Namensgebung sehr ernst genommen werden.
W\"ahrend die Namen von Funktionen und Skripten ihren Zweck
beschreiben, sollten die Namen von Variablen ihren Inhalt
@@ -278,14 +279,17 @@ ein v\"ollig unn\"otiger Kommentar.
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.
R\"uckgabewerte beschreibt. Mit dem \code{help}- Befehl wird dieser
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}
\item In wenigen Zeilen kurz den Zweck der Funktion beschreiben.
\item Den Funktionskopf nocheinmal hinschreiben, damit
klar ist, in welcher Reihenfolge Argumente \"ubergeben werden.
\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).
@@ -333,7 +337,7 @@ lokale Funktion.
\pagebreak[3]
\lstinputlisting[label=localfunctions, caption={Beispiel f\"ur den
Einsatz von lokalen Funktionen.}]{calculate_sines.m}
Einsatz von lokalen Funktionen.}]{calculateSines.m}
Lokale Funktionen existieren in der gleichen Datei und sind nur dort
verf\"ugbar. Jede Funktion hat ihren eigenen G\"ultigkeitsbereich, das
@@ -415,6 +419,6 @@ werden. Wenn diese nicht von globalem Interesse sind, kann mit
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:
achten!\footnote{Buchtip: Robert C. Martin:
\textit{Clean Code: A Handbook of Agile Software Craftmanship},
Prentice Hall}