Avatar

Ps0ke

Φίλιππος Στέφανος

Nocturnal Inclination

Nerdkram, Internethumor und der ganzen Rest.

Die Seminararbeit mit LaTeX

So jetzt ist es auch bei mir soweit: Die Seminararbeit (ehemalig Facharbeit) ist abgegeben. Mein Thema war im Bereich Lebensmittelchemie angesiedelt und das Thema lautetet: "Die Analyse des Mononatriumglutamatgehalts in Tomatenprodukten", also die Untersuchung des Gehalts eines Geschmacksverstärkers in Tomatensuppen. Wen das interessiert, der kann sie hier lesen. In diesem Blogpost soll es aber eher um den Entstehungsprozess gehen.

Das Besondere an eben jenem ist nämlich, dass die Arbeit nicht wie bei den meisten meiner Mitschüler*innen in Microsoft Offices Word oder Open-/Libre-Namensverwirrungsoffices Writer oder gar Apple iWorks Pages geschrieben, sondern mit dem professionellen LaTeX (sprich: latech) Satzsystem erzeugt wurde. Damit bin ich zwar nicht allein--Ro0mquy, Fabian, duzeful, Araxegon und Norbert haben ebenfalls "geTeXt", Alexander wird es bestimmt auch tun--allerdings doch deutlich in der Minderheit. Warum? Weil LaTeX kein Textverarbeitungsprogramm ist, sondern enie Auszeichnungssprache und ein Satzprogramm. Zur Formatierung markiert man nicht ein Wort und klickt auf "Fett", sondern man schreibt die Auszeichnung direkt in den "Code": \textbf{Wort}. Bilder werden nicht nicht per drag-n-drop in das Dokument gezogen, sondern mit

\begin{figure}
    \includegraphics{bild}
    \caption{Eine Bildunterschrift}
\end{figure}

eingebunden. Das sieht auf den ersten Blick sehr kompliziert aus, doch mir liegt dies Art zu arbeiten viel eher, als mit Word oder seinen Kumpanen. Ich kann meinen Lieblingseditor verwenden, den Text in verschiedene Dateien unterteilen, also modularisieren und das ganze sogar mit git verwalten. Ich kann überall, und wenn ich auch nur eine Kommandozeile mit nano oder vim habe schnell Änderungen vornehmen und binde mich nicht an ein properitäres Dateiformat, oder eines, bei dem ich eine riesige GUI-Software starten muss um es lesen. Noch dazu sieht es einfach verdammt gut aus und erfüllt höchste typographische Ansprüche.

Der wichtigste Aspekt war allerdings für mich, dass sich LaTeX hervorragend für das Schreiben naturwissenschaftlicher Arbeiten eignet. Der Formelsatz ist exzellent, die Verwaltung der Bibliographie funktioniert mit BibTeX unkompliziert und zuverlässig und man kann sogar mit den entsprechenden Paketen chemische Strukturformeln erzeugen.

Natürlich ist es viel Arbeit, da man sich--hat man sich vorher noch nicht mit LaTeX auseinandergesetzt--erst einmal an die doch etwas befremdliche Syntax gewöhnen muss. Doch ich persönlich glaube, dass ich, um den gleichen Grad an Perfektion zu erreichen, in Word o.Ä. länger gebraucht hätte. Da LaTeX seit den Siebziegern existiert und von Wissenschaftlern rund um die Welt eigesetzt wird, ist so gut wie jedes Problem bereits aufgetreten und gelöst worden. Wenn man sich mit LaTeX beschäftigt, kann ich einem nur das Wikibook und tex.stackexchange empfehlen, dort finden man Antworten auf fast alle Fragen. CTAN eignet sich hervorragend, um Dokumentation zu Paketen nachzuschlagen. Für diejenigen, die ebenfalls vorhaben, ihre Arbeit in LaTeX zu schreiben, möchte ich hier jetzt noch einige Empfehlungen abgeben.

Zum einen hätten wir da das Paket csquotes, das euch, neben einer Reihe weiterer Befehlen, \enquote{foo} zur Verfügung stellt. Damit könnt ihr ganz einfach Anführungszeichen setzen und erspart euch die nervige ,,foo'' Syntax. Die Anführungszeichen werden dann für euer jeweiliges babel-Setting korrekt eingefügt.

Eine weitere Erleichterung ist das siunitx Paket. Mit ihm setzt ihr korrekt Einheiten, wie z.B. \SI{23}{\milli\gram\per\litre}. Es bietet umfangreiche Einstellungsmöglichkeiten und erweiterte Funktionen um beispielsweise Zahlenbereiche oder Listen zu formatieren oder sogar automatisch zu runden.

Die Pakete tabularx, multirow und caption erweitern den Tabellensatz um nützliche Features und booktabs sorgt dafür, dass eure Tabellen wunderschön und professionell aussehen. Weiteres dazu im Wikibook.

Wer seine Arbeit im Bereich Chemie schreibt, für den werden die Pakete chemfig und mhchem zum Erzeugen von komplexen Strukturformelgleichungen und einfachen Formatieren von Summenformeln interessant sein. Sämtliche chemischen Abbildungen in meiner Arbeit sind mit chemfig gebaut. Es ist zwar auch eine Menge Arbeit, allerdings kann man so mit einem Textediror Änderungen einarbeiten und muss keine Graphiksoftware starten oder sich Monster wie [ChemSektch] zulegen. Wer jedoch häufig etwas in diesem Bereich zu Zeichnen hat, und sich mit graphischer Software auskennt, wird damit jedoch bestimmt glücklicher, da die chemfig-Syntax schnell sehr unübersichtlich werden kann.

Wer noch weitere nützliche Pakete sucht und sich generell mal die Struktur einer größeren Arbeit ansehen will, kann hier meine LaTeX-Quelldateien herunterladen. Das ganze steht unter Beerware-Lizenz (Verwende es und wenn es dir hilft, lass uns zusammen ein Bier--oder was anderes--trinken gehen). Dort finden sich auch sinnvolle Einstellungen für die obengenannten Pakete, ein Beispiel für die Strukturierung mit mehreren Dateien und die intensive Verwendung von chemfig zum malen von Chemieformeln.

Wer auch am Deutschhaus ist, und die Formatforlage für das Deckblatt und die Unabhängigkeitserklärung braucht, findet die von mir hier (v.1.1.0). Informationen zur Verwendung stehen im Readme.

An dieser Stelle möchte ich mich noch mal bei allen bedanken, die mir bei der Arbeit geholfen haben. Allen voran Dr. Markus Krischke vom Julius-von-Sachs-Institut für seine Hilfe bei den Probenmessungen, dann natürlich Christian Lorey vom Schülerlabor des FKG für seine umfangreiche Hilfe bei der Arbeit und die Bereitstellung des Labors, und auch Dr. Alfons Ledermann von der Fakultät für Chemie und Pharmazie der Uni Würzburg für das bereitwillige Korrekturlesen. Ein riesen Dankeschön bekommt natürlich noch mal Ro0mquy für die Hilfe mit chemfig; ohne ihn hätte ich mich endlos durch die Doku graben müssen. Ebenso danke ich petschge und urs und den andern aus #geeks für die Bereitstellung ihrer LaTeX-Templates und Hilfe bei Formatierungsproblemen.

Ich hab noch ein bisschen Statistik für die Nerds unter euch: Es sind 31 Seiten, 5 Kapitel, < 5697 Wörter (detex wirft noch ein paar Sachen raus, die nicht wirklich Wörter sind), das PDF ist 8,8MB groß, es sind 20 Abbildungen enthalten, 2 Tabellen und 3 Formeln. Aus meinem Git Repo kann ich außerdem noch entnehmen: Age: 76 days, 23 active days (30.26%); Total Files: 21; Total Lines of Code: 3087 (4067 added, 980 removed); Total Commits: 78 (average 3.4 commits per active day, 1.0 per all days). Ich hätte da noch einige Aktivitätsgraphen, die aber total unaussagekräftig sind (wie alle Werte aus Git hier), da da Bilder auch mit reingereichnet werden, und ein Absatz nur eine Zeile ist, eine Abbildung jedoch mindestens 5 Zeilen. Außerdem ist meine Commit-Policy nicht immer Einheitlich. Mal hab ich einen Commit nach einem ganzen Kapitel gemacht, mal nach ein paar kleinen Änderungen. Generell lässt sich jedoch sagen: Die Anzahl der Commits pro Tag und der hinzugefügten Zeilen nimmt mit veringertem Abstand zum Abgabetermin immer weiter zu. Außerdem hab ich vor allem zwischen 18 und 1 Uhr morgens committet. (Git Statistik von gitstat)

Die Software die zum Einsatz gekommen ist war: TextMate und Vim zur Text bearbeitung; Adobe Photoshop, Inkscape und graphix.sty zur Bildbearbeitung; Excalibur zum Auswerten von Spektren, Microsoft Word for Mac zum Betrachten der Formatvorlagen und zum exportieren der Excaliburdateien nach PDF m(; MacTeX 2012 als TeXLive Distribution, Latexmk.pl zum automatisierten Kompilieren; und natürlich git zur Versionskontrolle und iTerm2 als Terminalemulator; für die Präsentation werde ich Apple Keynote verwenden. Die Hardware zum Bilder machen waren: Nikon Coolpix P5000 und die Kamera des iPhone 3GS.


mdbl0g Benchmark

When you build a file based blog system like I did, mdbl0g, you are often told: "That'll be way too slow, especially in PHP!". As I don't blog too often and won't have too many posts, it didn't bother me. But what if..? This challenged me to benchmark my code. I wrote a small bash script to generate posts with random names quickly and put some "lorem ipsum" in there the size is varying because of the iterator but each one is around 2,629 bytes (~2.6kB) of size. So I set out to create and test with 1,000; 10,000 and 100,000 files, and the results are quite pleasing. Everything went well for 1,000 and 10,000 and if at all only a small delay occurred. But with 100,000 posts things got ugly. Although the main page rendered surprisingly fast, trying to search fucked up the server. I even pushed up the set_time_limit() in PHP, but the server threw a 500 Internal Server Error. I think no one will ever gather 100,000 blog posts and so this benchmark proves to me, that a file based approach is not so much of an performance issue if you have a reasonable amount of data. The network latency is the bottleneck!

Results

The time is measured inside the PHP script to determine pure script rendering time without network latency.

The script

You can find the full script pasted at GitHub:gist.

#!/usr/bin/env bash
if [[ $# -ne 2 ]]; then
    echo "Usage: $0 path/to/target/dir <Number of files to create>"
    exit
fi

for i in `seq 1 $2+1`; do
    year=`shuf -i 1900-2012 -n 1`
    month=`shuf -i 10-12 -n 1`
    day=`shuf -i 10-31 -n 1`
    hour=`shuf -i 10-23 -n 1`
    min=`shuf -i 10-59 -n 1`
    echo "$i $year-$month-$day\_$hour-$min.md"

cat <<EOF > $1$year-$month-$day\_$hour-$min.md
Benchmark post #$i
Here’s to the crazy ones. ...

Lorem ipsum dolor sit amet ...
Vivamus placerat, nunc a accumsan ...

Sed ultrices purus eu erat ...
EOF
done

1,000 Files (~2.5MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 1000
...
997 1922-11-29\_10-19.md
998 1915-10-10\_13-58.md
999 1913-11-15\_14-33.md
1000 1962-11-30\_13-13.md
./benchmark.sh posts/ 1000  2.07s user 7.08s system 65% cpu 13.909 total

% ls posts/ -1 | wc -l
999

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.02759s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
<!-- Execution Time: 0.23799s -->

10,000 Files (~25MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 10000
...
9997 1908-10-14\_20-58.md
9998 1990-12-25\_11-26.md
9999 1925-12-10\_17-39.md
10000 1967-11-19\_17-48.md
./benchmark.sh posts/ 10000  20.88s user 72.58s system 69% cpu 2:14.51 total

% ls posts/ -1 | wc -l
9990

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.11814s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
<!-- Execution Time: 0.70745s -->

100,000 Files (~250MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 100000
99997 1962-10-12\_16-57.md
99998 1982-11-31\_12-33.md
99999 1938-12-13\_12-38.md
100000 1971-12-25\_21-15.md
./benchmark.sh posts/ 100000  219.87s user 960.45s system 67% cpu 29:02.07 total

% ls posts/ -1 | wc -l
98992

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.75187s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
[1]    21563 done       noglob curl -L -s http://ps0ke.de/mdbl0g/search/crazy | 
       21565 exit 1     grep "Execution Time"

# set_time_limit(5*60); >> index.php line 2

% curl -L -s http://ps0ke.de/mdbl0g/search/crazy
An internal server error occurred. Please try again later.

IRC Webinterface auf dem eigenen Server installieren

Info

Nach dem ich in einem vorherigen Artiel bereits erklärt habe, wie man einen IRC-Server aufsetzt, möchte ich jetzt noch beschreiben, wie man ein Web-Frontend, qwebirc installiert. Damit können besucher auch ohne Client nur mit einem Webbrowser den Chat verwenden. qwebirc wird auch vom QuakeNet IRC Netzwerk verwendet, einem der größten IRC Netzwerke der Welt--sollte also gut skalieren ;)

Dependencies

Als erstes laden wir die Dependaecies für das in Python geschriebene qwebirc herunter. Das zope.interface ist über den Python-Package-Manager easy_install verfügbar.

$ easy_install zope.interface

Als nächstes brauchen wir das Twisted framework. In einem temporären Verzeichnes laden wir es herunter und installieren es. (Auf aktuelle Downloads prüfen!)

$ cd tmp
$ wget http://twistedmatrix.com/Releases/Twisted/12.1/Twisted-12.1.0.tar.bz2
$ bunzip2 Twisted-12.1.0.tar.bz2
$ tar xvf Twisted-12.1.0.tar
$ cd Twisted-12.1.0
$ python setup.py install

Installation & Konfiguration

Nun, da alle wichtigen Dependancies installiert sind (optionale können auf der qwebirc Website nachgeschlagen werden), können wir qwebirc installieren. Dazu wechseln wir ins Homeverzeichnis und laden den aktuellen Source-tree mit der Versioningsoftware 'Mercurial' herunter (Wer möchte kann auch tarballs auf der Website finden).

$ cd
$ hg clone http://hg.qwebirc.org/qwebirc/

Jetzt müssen wir den Service noch konfigurieren. Dafür kopieren wir die Standardeinstellungen und ändern nur die wichtigsten Details.

$ cd qwebirc
$ cp config.py.example config.py

Benutzt dafür den Terminaleditor eurer Wahl z.B. vim oder nano.

$ nano config.py

Hier einfach die Verbindungsdaten eures IRC-Servers eintragen

# OPTION: IRCSERVER
#         Hostname (or IP address) of IRC server to connect to.
# OPTION: IRCPORT
#         Port of IRC server to connect to.
IRCSERVER, IRCPORT = "irc.ps0ke.de", 2342

Verwendet hier am besten eine Subdomain, vielleicht auch die, unter der euer IRC Server sowieso läuft.

# OPTION: BASE_URL
#         URL that this qwebirc instance will be available at, add the
#         port number if your instance runs on a port other than 80.
BASE_URL = "http://irc.ps0ke.de"

So wie ihr euer Netzwerk auf im ngircd genannt habt.

# OPTION: NETWORK_NAME
#         The name of your IRC network, displayed throughout the
#         application.
NETWORK_NAME = "EosinIRC"

Aus nano kommt ihr mit ^x wieder raus, dann zum speichern bestätigen und fertig. Damit ist die Konfiguration abgeschlossen!

Jetzt noch das ganze "kompilieren".

$ ./compile.py

qwebirc verwendet einen eigenen Webserver, nicht den normalen Apache. Damit dieser Server von außen auch erreichbar ist, müssen wir dem Apache noch sagen, wie er Anfragen durch zu reichen hat. Dafür erstellen wir im DocumentRoot eine Subdomain (hier mal irc.ps0ke.de genannt. Das muss die gleiche sein, die ihr in config.py als BASE_URL eingetragen habt.)

$ cd /var/www/virtual/ps0ke
$ mkdir irc.ps0ke.de
$ cd irc.ps0ke.de
$ nano .htaccess

Hier müsst ihr nun den richtigen Port angeben.

RewriteEngine On
RewriteRule (.*) http://localhost:9090/$1 [P]

Test

Um die Funktionstüchtigkeit zu Testen, starten wir den Server erstmal im Vordergrund.

$ cd ~/qwebirc
$ python run.py --no-daemon

Wenn ihr den Server jetzt unter der von euch eingerichteten Adresse erreichen könnt, habt ihr alles richtig gemacht ;)

Falls ihr Fehlermeldungen bekommt weil Port 9090 schon belegt ist, müsst ihr beim starten des Servers noch mit --port=xxxx einen anderen Port angeben und diesen dann auch in der .htaccess richtig eintragen.

Service Einrichten

Damit der Server auch nach einem crash oder einer downtime wieder automatisch angeht, verwenden wir ihn als Service. Uberspace.de hat dafür deamontools installiert. Falls noch nicht geschehen einfach ein eigenes ~/service Verzeichnis mit dem mitgelieferten Skript erstellen

$ uberspace-setup-svscan

und dann einen einen qwebric Service einrichten

$ uberspace-setup-service qwebirc "~/qwebirc/run.py --no-daemon"

Allerdings produziert der Server so Fehlermeldungen und wird nicht funktionieren. qwebirc erwartet nämlich genauso wie etherpad-lite, in seinem Verzeichnis gestartet zu werden. Vorher natürlich den Service runterfahren.

$ svc -d ~/service/qwebirc
$ cd ~/service/qwebirc
$ nano run

Deshalb ändern wir das run-Skript des Services noch kurz ab und wechseln vor dem Start in das ~/qwebirc Verzeichnis.

# Now let's go!
cd ~/qwebirc

Jetzt den Service wieder hochfahren und alles sollte gehen!

$ svc -u ~/service/qwebirc

Eigenen IRC Server ohne root-Rechte installieren

Info

Eine kurze Anleitung, wie man einen IRC-Server ohne root-Rechte installiert. In diesem Beispiel gehe ich von der Serverkonfiguration von uberspace.de aus, es sollte aber ähnlich auch überall sonst funktionieren.

Installation

Als erstes laden wir ngircd runter, ein kleiner IRC Server, der kaum Konfiguration braucht und einfach funktioniert.

Entweder über den package manager toast

$ toast arm ngircd

oder mit cURL (aktuellste Version raussuchen)

$ curl http://ngircd.barton.de/pub/ngircd/ngircd-19.1.tar.gz -O
$ tar -zxvf ngircd-19.1.tar.gz

Die Variante bei toast hat dabei den Vorteil, dass Toast bereits alle nötigen Ordner und Strukturen perfekt einrichtet, dass ngircd nicht in den normalen, nur für root zugänglichen Pfaden sucht und waltet. Wie man das manuell einstellt weiß ich nicht. Da dies ein uberspace.de Tutorial sein soll, und toast bei uberspace.de standardmäßig installiert ist, kümmere ich mich auch nicht weiter darum.

Einstellungen

Nun richten wie die Konfiguratinsdateien ein.

$ ln -s ~/.toast/pkg/ngircd/v19.1/1/root/etc ~/ngircd
$ cd ngircd
$ cp ngircd.conf ngircd.org.conf
$ chmod 444 ngircd.org.conf

Dies erstellt einen symbolischen Link ngircd in euer Homeverzeichnis und erstellt eine nicht beschreibbare Kopie der Standardkonfigurationsdatei. Nun müsst ihr an der eigentlichen Konfigurationsdatei noch einige Einstellungen vornehmen. Benutzt dafür einen Terminaleditor euerer Wahl wie zum Beispiel vim oder nano.

$ nano ngircd.conf

[Global]
    Name = irc.{username}.{server}.ubserspace.de
    Info = Info Text
    # Globales Serverpasswort. Das ; am Anfang entfernen um es zu aktivieren
    ;Password = {password}

    # Information about the server and the administrator, used by the
    # ADMIN command. Not required by server but by RFC!
    AdminInfo1 = Description
    AdminInfo2 = Location
    AdminEMail = admin@irc.server

    # Bitte einen anderen als den Standard '6667' verwenden
    Ports = {port}

    MotdFile = /home/{username}/ngircd/ngircd.motd

    ServerUID = {username}
    ServerGID = {username}

[Operator]
    Name = {name}
    Password = {password}

Ihr müsst die Werte in den geschweiften Klammern natürlich mit euren Werten ersetzen (ohne Klammern dann). Wenn ihr wollt könnt ihr dann noch einige permanente Channels einrichten. Die Konfiguration dafür sieht so aus:

# ein passwortgeschützter Channel
[Channel]
    Name = #protected
    Topic = a closed channel
    Modes = tnPk
    Key = password

# ein offener Channel
[Channel]
    Name = #open
    Topic = an open channel
    Modes = tnP

Aus nano kommt ihr mit ^x wieder raus, dann zum speichern bestätigen und fertig.

Jetzt noch eine "Message of the Day" Datei anlegen

$ echo "Willkommen auf meinem IRC Server!" > ngircd.motd

Test

Jetzt testen wir die Konfiguration. Das geht mit

$ ngircd -t

Dabei sollten keine Fehler auftreten, wenn doch, nochmal genau die Konfigdatei anschauen! Jetzt testen wir ob der Server überhaupt funktioniert und starten ihn dafür im Vordergrund:

$ ngircd -n

Und von einer anderen Shell versuchen wir in den Server zu "telneten" (schnell tippen!)

$ telnet localhost {port}
USER tester localhost tester :name
NICK tester

Dabei sollten wir eine Antwort vom Server bekommen und in der Shell des Servers sollten wir den Client connecten sehen

Einen Service aufsetzen

Damit der Server auch nach einem crash oder einer downtime wieder automatisch angeht, verwenden wir ihn als Service. Uberspace.de hat dafür deamontools installiert. Falls noch nicht geschehen einfach ein eigenes ~/service Verzeichnis mit dem mitgelieferten Skript erstellen

$ uberspace-setup-svscan

und dann einen einen ngircd Service einrichten

$ uberspace-setup-service ngircd "ngircd -n"

Nun müsst ihr noch ein Portforwarding bei den Leuten von uberspace.de beantragen und fertig :)


The New Ps0ke 2012 Design

Ps0ke

HTML5

CSS3

License

Switched from cc-by-nc-sa to the more leaned-back MIT license. Shortly considered beerware, but it was just too vaporous. Wouldn't mind a beer, though!


2/17