<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PhiLIOsoph &#187; Tutorials</title>
	<atom:link href="http://www.robertnitsch.de/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.robertnitsch.de</link>
	<description>Ansichten, Erlebnisse und Werke eines Heranwachsenden</description>
	<lastBuildDate>Tue, 20 Jul 2010 19:27:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Datei-Backups leicht gemacht mit WinRAR</title>
		<link>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/</link>
		<comments>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 15:00:30 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=413</guid>
		<description><![CDATA[WinRAR kann man ganz leicht als Backup-Tool für Dateien und Verzeichnisse nutzen. Das hat einige Vorteile: Der Backup-Vorgang ist durchschaubar bzw. leicht nachvollziehbar, weil es sich um einen gewöhnlichen Packer handelt und nicht um eine spezielle Backup-Software, bei der man so genau gar nicht weiß, wie sie arbeitet (das kann ich persönlich gar nicht leiden). [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.winrar.de" class="liexternal">WinRAR</a> kann man ganz leicht als Backup-Tool für Dateien und Verzeichnisse nutzen. Das hat einige Vorteile:</p>
<ul>
<li>Der Backup-Vorgang ist durchschaubar bzw. leicht nachvollziehbar, weil es sich um einen gewöhnlichen Packer handelt und nicht um eine spezielle Backup-Software, bei der man so genau gar nicht weiß, wie sie arbeitet (das kann ich persönlich gar nicht leiden).</li>
<li>RAR-Dateien kann man (im Gegensatz zu den meisten Backup-Containern kommerzieller Backup-Software, bspw. Acronis True Image) nahezu auf jeder Plattform entpacken, weil der Entpack-Algorithmus öffentlich verfügbar ist. Das gilt natürlich auch für ZIP, 7zip und die meisten anderen Archiv-Formate.</li>
<li>Das RAR-Format unterstützt sogenannte <em>recovery records</em> (Wiederherstellungsinformationen). Kleinere Schäden an der Backup-Datei (Beispiel: ein paar Sektoren auf der Festplatte spielen verrückt) können damit behoben werden.</li>
<li>Die Verschlüsselung von RAR-Dateien erfolgt &#8211; wenn gewünscht &#8211; mit <a href="http://de.wikipedia.org/wiki/Advanced_Encryption_Standard" rel="nofollow" class="liwikipedia">AES-128</a>. Dieser Standard gilt als sicher.</li>
</ul>
<p>Im Folgenden zeige ich mit welchen Einstellungen man WinRAR für Backups optimiert.</p>
<h3>Einstellungen: &#8220;Allgemein&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_Allgemein.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/00_Allgemein.png" alt="WinRAR - Allgemeine Einstellungen" title="00_Allgemein" width="452" height="411" class="alignright size-full wp-image-423" /></a></p>
<ol>
<li>Ziel-Datei: In welcher Archivdatei sollen die Dateien gesichert werden?</li>
<li>Update-Modus: Das Backup-Archiv soll mit den Quelldaten synchronisiert werden. Das bedeutet, dass neue Dateien hinzugefügt, geänderte Dateien erneuert und gelöschte Dateien auch im Backup gelöscht werden. Hierdurch werden außerdem das 2. und alle folgenden Backups stark beschleunigt, weil quasi-inkrementelle Backups gemacht werden.</li>
<li>Kompressions-Methode: Damit das Komprimieren nicht zu viel Zeit in Anspruch nimmt stellen wir die Kompression auf eine schwächere aber schnellere Stufe.</li>
<li>Authentizitätsinformationen hinzufügen: Fügt bei der Erstellung des Archivs nochmal einige allgemeine Daten wie Archivname etc. in das Archiv ein. Diese werden beim späteren Öffnen des Archivs geprüft, um grobe Manipulationen zu verhindern. Bietet zwar wenig Sicherheit, kostet aber auch nichts.</li>
<li>Wiederherstellungs-Informationen hinzufügen: Hier handelt es sich um den oben beschriebenen <em>recovery record</em>. Unter <em>Erweitert</em> kann man dieses Feature genauer konfigurieren.</li>
</ol>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Erweitert&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_Erweitert.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/01_Erweitert.png" alt="WinRAR - Erweiterte Einstellungen" title="01_Erweitert" width="441" height="400" class="alignright size-full wp-image-431" /></a></p>
<p>Einstellungen, die sehr nützlich sind, aber dem persönlichen Gutdünken obliegen, habe ich blau eingerahmt.</p>
<p>Zu den roten Markierungen:</p>
<ol>
<li>Datenströme speichern: Sehr wichtig, wenn NTFS als Dateisystem eingesetzt wird. Einige Applikationen legen in zusätzlichen NTFS-Dateiströmen einige Informationen ab, die nicht zu den Dateiinhalten selbt gehören, aber mit den jeweiligen Dateien verknüpft sind. Es handelt sich quasi um eine Art von <em>Meta-Informationen</em>, die ohne diese Einstellungen verlorengehen würden.</li>
<li>Wiederherstellungs-Informationen: Hiermit legt man fest, wie groß der prozentuale Anteil des recovery records am Archiv sein soll. 2-5% halte ich für angemessen. Standard ist übrigens 1%.</li>
</ol>
<p>Zu den &#8220;Volumen&#8221;-Einstellungen: Diese sind nur nutzbar, wenn man das Backup-Archiv in mehrere Teilarchive aufsplittet. Dazu muss man eine Volumengröße unter &#8220;Allgemein&#8221; angeben.<br />
Jedes &#8220;Wiederherstellungs-Volumen&#8221; kann genau 1 Original-Volumen wiederherstellen, sogar dann, wenn dieses komplett verloren gegangen ist. Angenommen man hat 30 Teil-Archive (&#8220;Volumen&#8221;) und 3 Wiederherstellungsvolumen, dann dürfen bis zu 3 Volumen verlorengehen bzw. beschädigt werden. Im Zweifel lohnt sich hier ein Blick in die WinRAR-Hilfe.</p>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Dateien&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_Dateien.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/02_Dateien.png" alt="WinRAR - &quot;Dateien&quot;" title="02_Dateien" width="452" height="411" class="alignright size-full wp-image-444" /></a></p>
<p>Der wahrscheinlich wichtigste Teil am Backup: Die zu sichernden Dateien bzw. Verzeichnisse müssen ausgewählt werden.</p>
<p>Hier kann man außerdem bestimmte Dateien bzw. Verzeichnisse vom Backup ausschließen. Bei mir gehören zum Beispiel Downloads definitiv zu den ausgeschlossenen Daten. *.tmp sowie *.bak-Dateien brauchen genausowenig gesichert zu werden.</p>
<p>Ebenfalls sehr nützlich ist es, bestimmte Dateien zwar zu sichern, aber dabei von der Kompression auszuschließen. Das macht das Backup dieser Dateien/Dateitypen deutlich schneller. Zum Beispiel macht es wenig Sinn *.rar, *.zip oder *.jpg-Dateien zu komprimieren, weil diese Dateien bereits komprimiert vorliegen. Ein paar weitere Vorschläge für diesen Filter: *.mp3 *.avi *.mpg</p>
<p>Aufpassen muss man bei der Struktur des zu erzeugenden Archivs. Ich spreche mich sehr stark für die Einstellung <em><strong>&#8220;Volle Pfade inkl. Laufwerksbuchstaben&#8221;</strong></em> aus, damit nicht nur die Daten selbst, sondern auch ihr genauer Ablageort jederzeit wiederherstellbar bzw. nachvollziehbar ist. In der Standardeinstellung gehen diese Informationen verloren und bei vielen Dateien wird das sehr schnell sehr hässlich, weil man nicht mehr unterscheiden kann, woher die Dateien/Ordner im Einzelnen gekommen sind.</p>
<div style="clear:both;"></div>
<h3>Einstellungen: &#8220;Backup&#8221;</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_Backup.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/03_Backup.png" alt="WinRAR - &quot;Backup&quot;" title="03_Backup" width="452" height="411" class="alignright size-full wp-image-450" /></a></p>
<p>Wie der Name sagt sind diese Einstellungen speziell für Backups vorgesehen.</p>
<p><strong>&#8220;Gemeinsam genutzte Dateien öffnen&#8221;</strong> sorgt dafür, dass WinRAR versucht, auch momentan durch andere Programme geöffnete Dateien zu sichern. Nichtsdestotrotz wird WinRAR das bei vielen Dateien mit einer Fehlermeldung quittieren. Das ist aber völlig normal.</p>
<p><strong>&#8220;Archivnamen aus folgender Maske erzeugen&#8221;</strong> hängt an den Archivnamen eine Zeichenkette an, die dynamisch zum Beispiel aufgrund der aktuellen Kalenderwoche erzeugt wird. In meinem Fall wird &#8220;yyyymm&#8221; angehängt, also z.B. &#8220;201001&#8243;. Dadurch wird maximal 1 Monat lang einunddasselbe Archiv genutzt (&#8220;RobertBackup201001.rar&#8221;). Für den nächsten Monat erzeugt WinRAR automatisch ein neues Archiv (&#8220;RobertBackup201002.rar&#8221;).<br />
Folgende Zeichen werden in der Maske akzeptiert (aus der WinRAR &#8211; Hilfe; dort findet man weitere nützliche Details):</p>
<table>
<tr>
<th>Y</th>
<td>Jahr</td>
</tr>
<tr>
<th>M</th>
<td>Monat</td>
</tr>
<tr>
<th>MMM</th>
<td>Monatsnamen (Jan, Feb, usw.)</td>
</tr>
<tr>
<th>W</th>
<td>Kalenderwoche (eine Woche beginnt mit einem Montag)</td>
</tr>
<tr>
<th>A</th>
<td>Tag der Woche (Montag ist 1, Sonntag ist 7)</td>
</tr>
<tr>
<th>D</th>
<td>Tag des Monats</td>
</tr>
<tr>
<th>E</th>
<td>Tag des Jahres</td>
</tr>
<tr>
<th>H</th>
<td>Stunden</td>
</tr>
<tr>
<th>M</th>
<td>Minuten (wird als Minuten behandelt, wenn es nach Stunden auftritt)</td>
</tr>
<tr>
<th>S</th>
<td>Sekunden</td>
</tr>
<tr>
<th>N</th>
<td>Archivnummer. WinRAR sucht nach einem bereits vorhandenen Archiv mit dem erzeugten Namen und erhöht im Falle der Existenz die Archivnummer, bis ein eindeutiger Name erzeugt wurde. Das Formatzeichen &#8216;N&#8217; wird beim Erstellen von mehrteiligen Archiven (Volumen) nicht unterstützt.</td>
</tr>
</table>
<p>Damit kann man schon eine ganze Menge erreichen. In diesem Punkt steht WinRAR kommerzieller Backup-Software in nichts nach, eher im Gegenteil. Lediglich das Löschen alter Archive geschieht nicht so leicht automatisch, da muss man schon noch selbst Hand anlegen. Aber um ehrlich zu sein lösche ich meine Backups auch viel lieber selbst&#8230;</p>
<div style="clear:both;"></div>
<h3>Kommentar hinzufügen</h3>
<p>Im letzten Reiter kann man dem Archiv einen Kommentar hinzufügen. Beispiel:</p>
<blockquote><p>In diesem Backup enthalten:<br />
C:\Users\Robert\<br />
D:\eclipse</p>
<p>Ausgeschlossen:<br />
C:\Users\Robert\Downloads *.tmp *.bak </p>
<p>Backup-Methode: Synchronisation (geänderte/neue Dateien werden hinzugefügt/überschrieben, gelöschte Dateien werden aus dem Archiv gelöscht)</p></blockquote>
<h3>Speichern der Einstellungen als Profil</h3>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_Profile.png" class="liimagelink"><img src="http://www.robertnitsch.de/wp-content/uploads/2010/01/04_Profile.png" alt="WinRAR - &quot;Aktuelle Einstellungen als Profil speichern...&quot;" title="04_Profile" width="452" height="411" class="alignright size-full wp-image-455" /></a></p>
<p>Nun wäre das ganze ziemlich mühselig, wenn man all diese Einstellungen jedes Mal aufs Neue festlegen müsste. Dafür bietet WinRAR sogenannte Profile an. Unter &#8220;Allgemein&#8221; kann man seine Einstellungen auf diese Weise für das nächste Mal speichern (siehe Bild auf der rechten Seite).</p>
<p><strong>Nicht vergessen im folgenden Dialog die ersten beiden Haken anzukreuzen! Außerdem empfehle ich einen Haken bei &#8220;Verknüpfung auf dem Desktop anlegen&#8221;.</strong> Diese Verknüpfung sollte man immer mit Administratorrechten ausführen (kann man in den Einstellungen derselben auch dauerhaft festlegen).</p>
<div style="clear:both;"></div>
<h3>Fazit</h3>
<p>Backups mit WinRAR sind schnell, klein, übersichtlich, leicht zu konfigurieren und sicher. Mit Hilfe der Einstellung <strong>&#8220;Archivnamen aus folgender Maske erzeugen&#8221;</strong> kann man zudem eine automatische Konsolidierung der Backups umsetzen.</p>
<p>Was will man mehr?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2010/01/11/datei-backups-leicht-gemacht-mit-winrar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java Generics vs. Java Listen</title>
		<link>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/</link>
		<comments>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 20:09:35 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=211</guid>
		<description><![CDATA[Beim Thema Generics in Verbindung mit Listen geht vieles drunter und drüber. Dabei ist die Sache gar nicht so schwer, wenn man das Prinzip einmal verstanden hat&#8230; Zunächst einmal: Generics ermöglichen mittels formaler Typparamter, dass Klassen (und Funktionen), die bestimmte Dienste zur Verfügung stellen, mit mehreren Datentypen umgehen können. Wenn wir zum Beispiel zwei beliebige [...]]]></description>
			<content:encoded><![CDATA[<p>Beim Thema Generics in Verbindung mit Listen geht vieles drunter und drüber. Dabei ist die Sache gar nicht so schwer, wenn man das Prinzip einmal verstanden hat&#8230;</p>
<p>Zunächst einmal: Generics ermöglichen mittels <em>formaler Typparamter</em>, dass Klassen (und Funktionen), die bestimmte Dienste zur Verfügung stellen, mit mehreren Datentypen umgehen können.<br />
Wenn wir zum Beispiel zwei beliebige Objekte als &#8220;Paar&#8221; verwalten wollen, dann benötigen wir eine entsprechende Klasse mit zwei Attributen, einer Möglichkeit die Objekte darin zu speichern und wieder auszulesen.</p>
<p>An sich nichts schweres:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Pair <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">Object</span> obj1, obj2<span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Das Einspeichern von Objekten ist der Einfachheit halber nur beim Erzeugen des Paares möglich...</span>
    Pair<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj1, <span style="color: #003399;">Object</span> obj2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span> <span style="color: #339933;">=</span> obj1<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span> <span style="color: #339933;">=</span> obj2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getFirst<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getSecond<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Diese Klasse hat aber einen Haken. Beim Einspeichern gehen die Informationen über den Typ der eingespeicherten Objekte verloren. Wenn wir den Typ wiederherstellen wollen müssen wir einen expliziten Cast durchführen. Andernfalls erhalten wir immer nur <em>Object</em>s.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Pair paar <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Pair<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
MeinApfel apfel <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>MeinApfel<span style="color: #009900;">&#41;</span>paar.<span style="color: #006633;">getFirst</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bei Listen ist das Problem noch dramatischer. Ohne Generics muss man bei jeder Leseoperation auf einer Liste explizit casten:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">Vector</span> liste <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Vector</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    liste.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>liste.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    esseApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>MeinApfel<span style="color: #009900;">&#41;</span> liste.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bei so vielen expliziten Casts riskiert man außerdem <em>ClassCastException</em>s, falls das referenzierte Objekt nicht zu dem entsprechenden Typ konvertiert werden kann.</p>
<p>Abhilfe schaffen hier die Generics. Das soll erstmal am Beispiel der obigen Pair-Klasse demonstriert werden, die folgendermaßen generisch gemacht werden kann:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Pair<span style="color: #339933;">&lt;</span>A,B<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span>
    A obj1<span style="color: #339933;">;</span>
    B obj2<span style="color: #339933;">;</span>
    Pair<span style="color: #009900;">&#40;</span>A obj1, B obj2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span> <span style="color: #339933;">=</span> obj1<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span> <span style="color: #339933;">=</span> obj2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> A getFirst<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> B getSecond<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">obj2</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>A und B sind sogenannte formale Typparameter, die in diesem Fall für beliebige Typen stehen.<br />
Folgendermaßen erzeugen wir jetzt Paare von Integer-Objekten:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// anschaulich wird hier A = Integer und B = Integer gesetzt</span>
Pair<span style="color: #339933;">&lt;</span>Integer, Integer<span style="color: #339933;">&gt;</span> paar <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Pair<span style="color: #339933;">&lt;</span>Integer, Integer<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// kein Cast mehr nötig, weil auch die Signatur von getFirst() quasi dynamisch an Integer angepasst wurde</span>
<span style="color: #003399;">Integer</span> zahl <span style="color: #339933;">=</span> paar.<span style="color: #006633;">getFirst</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dasselbe ist natürlich auch bei Listen möglich, die bei der Einführung der Generics auch gleich generisch gemacht wurden. Bei Listen gibt es im Gegensatz zu dem Pair-Beispiel nur <em>einen</em> formalen Typparameter, der den Typ der gespeicherten Elemente festlegt.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Eine Liste von Elementen des Typs &quot;MeinApfel&quot; anlegen...</span>
Vector<span style="color: #339933;">&lt;</span>MeinApfel<span style="color: #339933;">&gt;</span> liste <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>MeinApfel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
liste.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> MeinApfel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// funktioniert problemlos, da die Signatur von get() genau wie getFirst() aus dem ersten Beispiel an den ggb. Typ angepasst wurde</span>
MeinApfel apfel <span style="color: #339933;">=</span> liste.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Richtig trickreich wird es, wenn Funktionen, die Listen entgegennehmen, generisch gemacht werden sollen. Angenommen wir wollen eine Funktion schreiben, die eine Liste von Nahrungsmitteln entgegennimmt und ihr Gewicht bestimmt.<br />
In diesem Fall werden sogenannte Wildcards benötigt.</p>
<p>Intuitiv müsste die Funktion folgendermaßen aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">double</span> wiege<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span> liste<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Diese Funktion würde aber entgegen unserer Intuition bspw. keine Liste mit Äpfeln annehmen, obwohl Äpfel in der Klassenhierarchie ganz klar ein Subtyp von Nahrungsmittel darstellen würden (<em>public class Apfel extends Nahrungsmittel</em>).<br />
Es funktioniert deshalb nicht, weil List&lt;Apfel&gt; einfach nicht kompatibel ist zu List&lt;Nahrungsmittel&gt;. Beispiel:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Vector<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span> liste1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>Nahrungsmittel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// OK!</span>
Vector<span style="color: #339933;">&lt;</span>Apfel<span style="color: #339933;">&gt;</span> liste2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Vector<span style="color: #339933;">&lt;</span>Apfel<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// OK!</span>
liste1 <span style="color: #339933;">=</span> liste2<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// FEHLER: cannot convert from Vector&lt;Apfel&gt; to Vector&lt;Nahrungsmittel&gt;</span></pre></td></tr></table></div>

<p>Dieser Code wird vom Compiler deshalb nicht akzeptiert, weil man in eine Liste von Äpfeln keine Nahrungsmittel einfügen kann. Wenn <em>liste1</em> vom Typ List&lt;Nahrungsmittel&gt; auf <em>liste2</em> vom Typ List&lt;Apfel&gt; verweisen würde, dann würde das bspw. die Signatur von liste1.add(&#8230;) verletzen, denn liste1.add(new Nahrungsmittel()) wäre nicht möglich, weil liste1 auf eine Liste von Äpfeln (und nur Äpfel!) zeigen würde. Das meine ich, wenn ich schreibe, dass List&lt;Apfel&gt; nicht kompatibel ist zu List&lt;Nahrungsmittel&gt;.</p>
<p>Das Problem löst man mit besagten Wildcards:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">double</span> wiege<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;?</span> <span style="color: #000000; font-weight: bold;">extends</span> Nahrungsmittel<span style="color: #339933;">&gt;</span> liste<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// akzeptiert alle Listen, deren Elemente Nahrungsmittel oder Subtypen davon sind</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>? steht für einen unbekannten Typ. Bekannt ist bei einer List&lt;?&gt; nur, dass &#8211; wie bei jeder typ-parametrisierten Liste &#8211; die Elemente, die in der Liste gespeichert sind, alle vom selben (unbekannten) Typ sind.<br />
Das &#8220;extends Nahrungsmittel&#8221; schränkt die möglichen Typen hier aber insofern ein, als dass Nahrungsmittel die &#8220;obere Schranke&#8221; darstellt. ? darf hier also vom Typ Nahrungsmittel oder ein Subtyp davon sein.</p>
<p>Es gibt auch die Möglichkeit eine untere Schranke zu definieren: List&lt;? super Nahrungsmittel&gt; bzw. allgemein List&lt;? super X&gt;. Erlaubt sind dann Elemente vom Typ X oder Supertypen davon.</p>
<p>Bleiben wir zunächst bei unserer List&lt;? extends Nahrungsmittel&gt;. Wir können zumindest eingeschränkt mit einer solchen Liste arbeiten: Lesen, aber nicht Einfügen. Das Einfügen klappt deshalb nicht, weil der genaue Typ der Liste nicht bekannt ist. Zwar kann man einen Apfel zu einem Nahrungsmittel konvertieren. Aber die Liste enthält ja nicht notwendigerweise Nahrungsmittel. Sie kann genausogut Birnen enthalten &#8211; daher darf man in eine solche Liste keine neuen Objekte einfügen.</p>
<p>Im Folgenden eine Tabelle, die die erlaubten Operationen auf einer Liste dokumentiert:</p>
<table border="1" class="data">
<tr>
<th>Typ</th>
<th>Lesen</th>
<th>Typ der gelesenen Objekte</th>
<th>Einfügen</th>
<th>Einfügbare Typen</th>
</tr>
<tr>
<th style="text-align:left;">List</th>
<td>Ja</td>
<td>Object</td>
<td>Ja</td>
<td>Beliebig</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;?&gt;</th>
<td>Ja</td>
<td>Object</td>
<td>Nein</td>
<td>-</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;X&gt;</th>
<td>Ja</td>
<td>X</td>
<td>Ja</td>
<td>X oder Subtypen von X</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;? extends X&gt;</th>
<td>Ja</td>
<td>X</td>
<td>Nein</td>
<td>-</td>
</tr>
<tr>
<th style="text-align:left;">List&lt;? super X&gt;</th>
<td>Ja</td>
<td>Object</td>
<td>Ja</td>
<td>X oder Subtypen von X</td>
</tr>
</table>
<p>Bleibt nur noch die Frage zu klären, warum man in eine List&lt;? super X&gt; Elemente vom Typ X und Subtypen von X einfügen darf. Bei List&lt;? extends X&gt; ist das schließlich auch nicht möglich. Nunja, bei <em>extends X</em> sind die Elemente der Liste vom Typ X oder Subtypen davon, d.h. <em>spezieller</em>. Bei <em>super X</em> sind die Elemente vom Typ X oder Supertypen von X, d.h. <em>allgemeiner</em>. Daher kann man Objekte vom Typ X oder von einem Subtyp von X nach Belieben in eine solche Liste einfügen, weil man Objekte von einem bestimmten Typ immer zu einem allgemeineren Typ konvertieren kann.<br />
Faustregel: Jeder Apfel ist ein Obst, aber nicht jedes Obst ein Apfel!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2009/03/31/java-generics-vs-java-listen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Das Studentenleben an der Universität</title>
		<link>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/</link>
		<comments>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 21:04:56 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Erfahrungsberichte]]></category>
		<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Schule]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=130</guid>
		<description><![CDATA[In diesem Artikel möchte ich aus meiner Sicht als Erstsemester kurz und knapp beschreiben, was man als Student während der Vorlesungszeit so macht. Als ich noch Schüler war, habe ich mir einen solchen Text gewünscht. Die Beschreibungen beziehen sich auf meine eigenen Erfahrungen. Ich bemühe mich zwar, alles so allgemein wie möglich zu halten, kann [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Artikel möchte ich aus meiner Sicht als Erstsemester kurz und knapp beschreiben, was man als Student während der Vorlesungszeit so macht. Als ich noch Schüler war, habe ich mir einen solchen Text gewünscht. Die Beschreibungen beziehen sich auf meine eigenen Erfahrungen. Ich bemühe mich zwar, alles so allgemein wie möglich zu halten, kann aber nicht dafür garantieren, dass es an anderen Universitäten nicht wesentlich anders abläuft. Ich kann auch nicht garantieren, dass alle Angaben korrekt sind und behalte mir Fehler vor. Feedback ist sehr erwünscht, vor allem wenn bestimmte Sachverhalte nicht ausreichend erklärt wurden bzw. unklar sind!</p>
<p>Wichtigster Unterschied zur Schule ist, dass an der Universität keine Allgemeinbildung gelehrt wird. Man kann stattdessen einen von vielen vielen vielen <strong>Studiengängen</strong> wählen. An manchen Universitäten werden mehr Studiengänge angeboten, an anderen weniger. <em>Ich</em> studiere momentan <strong>B.Sc. Informatik</strong> an der TU Darmstadt. B.Sc. bedeutet <strong>Bachelor of Science</strong> und ist ungefähr gleichwertig mit einem Vordiplom. Wenn man diesen Abschluss erreicht hat, dann bedeutet dies, dass man das <strong>Grundstudium</strong> abgeschlossen hat und das Hauptstudium, in welchem man sich i.d.R. weiter spezialisiert, antreten kann.</p>
<p>Jeder Studiengang besteht aus einer bestimmten <strong>Anzahl von Semestern</strong> &#8211; B.Sc. Informatik hat 6 Semester. Jedes Semester ist ein halbes Jahr lang &#8211; man unterscheidet zwischen <strong>Wintersemester</strong> (1. Oktober bis 31. März) und <strong>Sommersemester</strong> (1. April bis 30. September).</p>
<p>Jedes Semester wiederum besteht aus bestimmten <b>Lehrveranstaltungen</b>. Eine Lehrveranstaltung heißt zum Beispiel <a href="https://www3.mathematik.tu-darmstadt.de/?id=84&#038;evsid=23&#038;evsver=30" class="liexternal"><b>&#8220;Mathematik I für Inf und WInf&#8221;</b></a> (Inf=Informatiker, WInf = Wirtschaftsinformatiker) und besteht mindestens aus den zugehörigen <strong>Vorlesungen</strong>, <strong>Übungen</strong> und <strong>Prüfungen</strong>. Jede Lehrveranstaltung wird außerdem von einem <strong>Professor</strong>, dem verschiedene Hilfskräfte zur Seite stehen, geleitet.</p>
<p>In den <strong>Vorlesungen</strong>, die in sehr großen Hörsälen von dem jeweiligen Professor gehalten werden, wird der Stoff in sehr schnellem Tempo abgehandelt. Meistens muss man daher nach der Vorlesung einiges nacharbeiten, um den Stoff auch wirklich zu verinnerlichen. Die Vorlesungen dauern jeweils 2 <strong>Semesterwochenstunden (SWS)</strong>, von denen jede 45 Minuten lang ist. Generell wird an der Universität vieles in Semesterwochenstunden gemessen. Werden für eine Vorlesung zum Beispiel 4 SWS angeben, so heißt das, dass man in dem Semester jede Woche <em>durchschnittlich</em> (!) 4&#215;45 Minuten Vorlesung hat.<br />
(Die Teilnahme an den Vorlesungen ist nicht verpflichtend, aber ratsam.)</p>
<p>Beim Lernen des Stoffes helfen die <strong>Übungen</strong>, die von den Veranstaltern angeboten werden. Eine Übung findet meistens einmal pro Woche oder alle 2 Wochen statt und dauert i.d.R. 2&#215;45 Minuten. Da man nicht alle Hörer der Vorlesung in einer einzigen Übung betreuen kann, werden die Studenten verschiedenen <strong>Übungsgruppen</strong> zugeteilt. Jede Übungsgruppe besteht i.d.R. aus etwa 20-40 Studenten (das ist bei mir so) und wird von einem <strong>Tutor</strong> geleitet. Die Aufgabe des Tutors ist es, den Studenten zu helfen und ihre Fragen so gut es geht zu beantworten.<br />
Man trifft sich dann schließlich zu bestimmten Zeiten mit seiner Übungsgruppe und dem Tutor in einer Räumlichkeit der Universität und bearbeitet verschiedene <strong>Gruppenaufgaben</strong> zum Vorlesungsstoff, die jeweils vor der Übung veröffentlicht und von den Studenten ausgedruckt und mitgebracht werden sollen. Bei der Bearbeitung der Aufgaben soll das Gelernte eingeübt werden.<br />
(Die Teilnahme an den Übungen ist aber meistens nicht verpflichtend, aber wie bei den Vorlesungen ratsam.)</p>
<p>Es gibt allerdings nicht nur Gruppenaufgaben, sondern auch Hausaufgaben. Sie werden <b>Hausübungen</b> genannt. Diese Hausübungen sollen am besten alleine bearbeitet werden, damit man sich auch wirklich sicher sein kann, dass man die Aufgaben selbstständig lösen kann. Meistens ist es erlaubt, die Hausübungen auch in (kleinen!) Gruppen zu lösen &#8211; dies muss aber explizit angegeben werden und es muss trotzdem jeder Student seine eigene Lösung abgeben.</p>
<p>Die Hausübungen <em>kann</em> man am jeweils nächsten Übungstermin bei seinem Tutor abgeben (Anmerkung: bei manchen Lehrveranstaltungen kann man die Hausübungen auch online abgeben, natürlich besonders häufig in der Informatik und ähnlichen Fächern). Der Tutor wird die Lösungen dann bis zum nächsten Übungstermin korrigieren, ggf. sogar mit Anmerkungen versehen (wie man die Aufgabe z.B. hätte besser lösen können o.ä.).<br />
Wichtig: Bei vielen Lehrveranstaltungen steht es dem Studenten frei, ob er seine Hausübung bearbeitet und abgibt (auch, wenn er es im eigenen Interesse tun sollte).<br />
Bei manchen Lehrveranstaltungen werden die Hausübungen allerdings bewertet. Man nennt dies dann <strong>bewertete Hausübungen</strong>. Der Veranstalter kann dann zum Beispiel vorschreiben, dass man mindestens 50% der Punkte in den (bewerteten) Hausübungen erreichen muss, um für die Prüfung zugelassen zu werden. Die Bewertung wird von dem jeweiligen Tutor vorgenommen. Die Abgabe der Hausübungen ist bei solchen Lehrveranstaltungen natürlich Pflicht &#8211; ansonsten erhält man keine Punkte.</p>
<p>Zusätzlich zu den Vorlesungen und den Übungen gibt es bei manchen Lehrveranstaltungen auch noch <strong>Praktika</strong>, <strong>Seminare</strong> und weitere.<br />
Praktika sind zum Beispiel bei <strong>&#8220;Grundlagen der Informatik I&#8221;</strong> kleine Softwareprojekte, die ebenfalls benotet werden. Dabei kommt es vor allem darauf an, das Gelernte anzuwenden. Auch die Planung usw. fließen in die Bewertung ein.<br />
Seminare <del datetime="2009-01-01T16:50:34+00:00">sind, soweit ich das bisher überblicken kann, benotete Vorträge, für die sich Studenten selbstständig etwas tiefer in eine bestimmte Thematik einarbeiten mussten.</del> sind Lehrveranstaltungen kleineren Umfangs (meist über einige Wochen), an deren Ende das Gelernte entweder mit einer Hausarbeit oder einem Vortrag überprüft wird, woraus dann eine Note hervorgeht.</p>
<p>In den <strong>Prüfungen</strong> (der üblichen Lehrveranstaltungen) stellt sich schließlich heraus, ob die Studenten das nötige Wissen verinnerlicht haben und unter Zeitdruck anwenden können. Manche Prüfungen sind übrigens geteilt in zwei einzelne Klausuren (die dann für das Gesamtergebnis zusammengerechnet werden). Die Prüfungen finden während der <strong>Semesterferien</strong> statt. Es handelt sich also gar nicht um echte Ferien &#8211; es werden lediglich keine Vorlesungen mehr gehalten, daher auch <strong>vorlesungsfreie Zeit</strong> genannt.<br />
Zu den Prüfungen ist anzumerken, dass die Veranstalter teilweise komplizierte eigene Regelungen vorsehen. So ist es beispielsweise bei manchen Lehrveranstaltungen so, dass überschüssige Punkte aus den bewerteten Hausübungen zur Verbesserung der Prüfungsnote genutzt werden können. Wenn man sich in den entsprechenden Hausübungen gut schlägt, kann man seine Prüfungsnote am Ende also nochmal deutlich verbessern!<br />
Weiterhin ist zu sagen, dass man die Prüfungen in der Regel relativ leicht schaffen sollte, wenn man die Vorlesungen und Übungen regelmäßig besucht und seine Hausübungen macht. Der Stoff ist schwer, aber man bekommt viel Unterstützung bis zur Prüfung.</p>
<p>Wenn man eine Prüfung nicht besteht, muss man sie &#8211; wenn möglich &#8211; in einem späteren Semester wiederholen oder das Studium abbrechen. Meistens hat man eine begrenzte Anzahl von Versuchen.</p>
<p>Das waren so die wichtigsten Elemente des reinen Studentenlebens.<br />
Während der Vorlesungszeit geht man in die Vorlesungen, besucht die Übungen, macht seine Hausübungen usw. Wie viel Zeit das etwa kostet, kann ich noch nicht genau beschreiben, weil es im 1. Semester natürlich etwas langsamer los geht. Für die zweite Hausübung von <em>Grundlagen der Informatik I</em> habe ich aber immerhin fast 4 Stunden gebraucht. (Ich werde in einigen Wochen, wenn es richtig hart wird, an dieser Stelle einen kleinen Aufwandsvergleich zur Oberstufe einfügen.)<br />
Wenn die Vorlesungen dann vorbei sind, bereitet man sich auf die Klausuren vor. Das schwierigste dabei ist, dass es die meiste Zeit über niemanden gibt, der einen dazu zwingt, zu lernen. Es gibt Menschen, die damit besser umgehen können und es gibt Menschen, die damit eher nicht zurecht kommen &#8211; und der Stoff ist wirklich hart.</p>
<p>Alles in allem macht mir persönlich das Studium bisher wirklich Spaß! Das liegt zum einen daran, dass der Stoff wirklich anspruchsvoll ist und man definitiv nicht gelangweilt ist. Zum anderen ist es schlicht und ergreifend so, dass der Anteil dessen, was mich absolut nicht interessiert, sehr gering ist. Diese ganzen Schulfächer, die man ohne Weiteres aus dem Lehrplan streichen könnte, gibt es jetzt nicht mehr. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Als letzter Hinweis sei noch gesagt, dass für <strong>Erstsemester (Ersties)</strong> von der Universität oder von höhersemestrigen Studenten sogenannte <strong>Orientierungsphasen</strong> bzw. <strong>Einführungswochen</strong> angeboten werden. Alles, was in diesem Artikel beschrieben ist und noch viel viel mehr, wird dann innerhalb von 1 Woche o.ä. ausführlich erklärt. Man wird also auf keinen Fall im Regen stehen gelassen. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/11/01/das-studentenleben-an-der-universitat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenOffice Impress &#8211; printing handouts produces empty / blank / white pages</title>
		<link>http://www.robertnitsch.de/2008/05/07/openoffice-impress-printing-handouts-produces-empty-blank-white-pages/</link>
		<comments>http://www.robertnitsch.de/2008/05/07/openoffice-impress-printing-handouts-produces-empty-blank-white-pages/#comments</comments>
		<pubDate>Wed, 07 May 2008 13:01:31 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[drucken]]></category>
		<category><![CDATA[openoffice]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/?p=91</guid>
		<description><![CDATA[At least since OpenOffice 2.0 there is an issue with printing handouts for Impress presentations. (Impress is OpenOffice&#8217;s &#8220;PowerPoint&#174;&#8220;.) Normally, to get handouts printed, you switch to the &#8220;Handouts&#8221; view and print it, but for some reason a few people just get empty pages then. It doesn&#8217;t even matter, which operating system you&#8217;re using, the [...]]]></description>
			<content:encoded><![CDATA[<p>At least since OpenOffice 2.0 there is an issue with printing handouts for Impress presentations. (Impress is OpenOffice&#8217;s &#8220;PowerPoint<sup>&reg;</sup>&#8220;.)</p>
<p>Normally, to get handouts printed, you switch to the &#8220;Handouts&#8221; view and print it, but for some reason a few people just get empty pages then. It doesn&#8217;t even matter, which operating system you&#8217;re using, the problem is platform-independent.</p>
<p>Fortunately, there is at least one <em>good</em> message: The problem seems to be reproducible, as one official bug report, which is more than 2 years old, indicates: <a href="http://www.openoffice.org/issues/show_activity.cgi?id=62935" class="liexternal">http://www.openoffice.org/issues/show_activity.cgi?id=62935</a></p>
<p>Moreover, there is a workaround (linux only) for those, who really need to get there handouts printed:</p>
<ul>
<li>Switch to the standard view (where you edit your slides normally).</li>
<li>Export the presentation to PDF format.</li>
<li>Open your console/shell and execute the following command:<br />
<strong>pdfnup &#8211;nup 2&#215;2 &#8211;orient landscape &#8211;frame true &#8211;delta &#8220;1cm 1cm&#8221; &#8211;scale 0.9 &#8211;outfile <em>$OUTFILE</em> <em>$INFILE</em></strong></p>
<p><strong>pdfnup</strong> is part of the &#8220;PDFjam&#8221; package of tools, whose homepage is at <a href="http://www.warwick.ac.uk/go/pdfjam" class="liexternal">http://www.warwick.ac.uk/go/pdfjam</a>.<br />
<strong>$INFILE</strong> is the name of your presentation&#8217;s PDF file.<br />
<strong>$OUTFILE</strong> is the name of the PDF file your handout pages will be saved to.<br />
Replace <strong>landscape</strong> by <strong>portrait</strong> to change the orientation of your handout pages.<br />
<strong>2&#215;2</strong> can be replaced by <strong>CxR</strong>, where C is the number of columns and R is the number of rows per page.</li>
<li>Open $OUTFILE with your favorite PDF viewer. These are your handout pages! Hopefully, you can manage to get them printed.</li>
</ul>
<p>Indeed, this workaround (<a href="http://www.oooforum.org/forum/viewtopic.phtml?p=110532#110532" class="liexternal">original source</a>) really produces <strong>high-quality</strong> handouts (even better than the handouts that OpenOffice produces itself), but it is quite complicated and some options are missing.<br />
Anyway, if you need to get your handouts fast, this can save your life!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2008/05/07/openoffice-impress-printing-handouts-produces-empty-blank-white-pages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Lightning in shared Thunderbird profiles</title>
		<link>http://www.robertnitsch.de/2007/11/10/using-lightning-in-shared-thunderbird-profiles/</link>
		<comments>http://www.robertnitsch.de/2007/11/10/using-lightning-in-shared-thunderbird-profiles/#comments</comments>
		<pubDate>Sat, 10 Nov 2007 18:56:52 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.robertnitsch.de/2007/11/10/using-lightning-in-shared-thunderbird-profiles/</guid>
		<description><![CDATA[PLEASE NOTE: THIS ARTICLE IS OUTDATED. IT WAS WRITTEN FOR LIGHTNING 0.7 and 0.8! Normally, using Lightning in shared Thunderbird profiles isn&#8217;t possible, because there is one extension (.xpi) file for windows and another one for linux. For example, using the linux version under windows leads to terrible layout errors. Information: A &#8220;shared profile&#8221; is [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color:red; font-weight: bold;">PLEASE NOTE: THIS ARTICLE IS OUTDATED. IT WAS WRITTEN FOR LIGHTNING 0.7 and 0.8!</span></p>
<p>Normally, using Lightning in shared Thunderbird profiles isn&#8217;t possible, because there is one extension (.xpi) file for  windows and another one for linux. For example, using the linux version under windows leads to terrible layout errors.</p>
<blockquote><p>Information:</p>
<p>A &#8220;shared profile&#8221; is a profile which is used by more than one platform. E.g. it enables you to manage the same emails, addresses and bookmarks from either a windows or linux OS.</p></blockquote>
<p>Ssitter wrote some instructions for those who want to solve Lightning&#8217;s problem: <a href="http://wiki.mozilla.org/User:Ssitter/UnifiedLightning" class="liexternal">UnifiedLightning</a>. You just have to make a &#8220;combination&#8221; of the platforms&#8217; .xpi files.</p>
<p>When looking for such a combined .xpi file to download I haven&#8217;t found anything. Therefore I publish my own .xpi file for both windows and linux: <a href="http://files.robertnitsch.de/lightning-0.7-tb-linux-and-win.xpi" class="liinternal">lightning-0.7-tb-linux-and-win.xpi</a></p>
<h3>How to install Lightning for both windows and linux in a shared profile</h3>
<p><strong>Notice:</strong> This article has been written for Thunderbird 2. I am not sure whether it works when using other versions. Anyway, you use this .xpi file on your own risk!</p>
<ul>
<li>Start TB and remove the non-unified Lightning extension.</li>
<li>Restart TB and install <a href="http://files.robertnitsch.de/lightning-0.7-tb-linux-and-win.xpi" class="liinternal">the unified Lightning extension</a>.</li>
<li>Restart again and enjoy!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/11/10/using-lightning-in-shared-thunderbird-profiles/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP: Smarty und die Unterstützung mehrerer Sprachen / Multilingualität</title>
		<link>http://www.robertnitsch.de/2007/05/23/php-smarty-und-die-unterstutzung-mehrerer-sprachen-multilingualitat/</link>
		<comments>http://www.robertnitsch.de/2007/05/23/php-smarty-und-die-unterstutzung-mehrerer-sprachen-multilingualitat/#comments</comments>
		<pubDate>Wed, 23 May 2007 21:27:48 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://robertnitsch.de/2007/05/23/php-smarty-und-die-unterstutzung-mehrerer-sprachen-multilingualitat/</guid>
		<description><![CDATA[Smarty ist die Templateengine für PHP schlechthin. Smarty ist sehr schnell und kann einfach erweitert werden. In diesem Artikel geht es darum, wie man Smarty mehrsprachig betreiben kann bzw. die Templates sprachunabhängig umsetzen kann. Am Ende des Artikels kann der Code heruntergeladen werden. (Hinweis: In diesem Artikel wird PHP5 verwendet und vorrausgesetzt!) Mit Smarty und [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://smarty.php.net" class="liphp">Smarty</a> ist <em>die</em> Templateengine für PHP schlechthin. Smarty ist sehr schnell und kann einfach erweitert werden. In diesem Artikel geht es darum, wie man Smarty mehrsprachig betreiben kann bzw. die Templates sprachunabhängig umsetzen kann. <strong>Am Ende des Artikels kann der Code heruntergeladen werden.</strong></p>
<p>(Hinweis: <em>In diesem Artikel wird PHP5 verwendet und vorrausgesetzt!</em>)</p>
<p>Mit Smarty und ein paar Tricks ist es im Grunde sehr einfach, ein Projekt mehrsprachig zu gestalten. Dazu liest man alle nötigen Strings aus Sprachdateien aus und fügt sie an den jeweiligen Stellen ein. Freiwillige Übersetzer erstellen dann unterschiedliche Sprachdateien und man kann das Projekt auch in anderen Sprachen veröffentlichen.</p>
<p>Bei Smarty bedient man sich für diesen Zweck eines Prefilters. Ein solcher Prefilter verändert die Templates noch bevor sie von Smarty &#8220;kompiliert&#8221; werden.</p>
<p>So ist es z.B. möglich, ein Template wie folgt zu gestalten:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;table border=&quot;0&quot;&gt;
		&lt;tr&gt;
			&lt;td&gt;##user_form_username##&lt;/td&gt;
			&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;user&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;##user_form_password##&lt;/td&gt;
			&lt;td&gt;&lt;input type=&quot;password&quot; name=&quot;pass&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
		&lt;/tr&gt;
&lt;/table&gt;</pre></div></div>

<p>Die von Rauten (#) umschlossenen Zeichenketten spezifizieren einen bestimmten Sprach-String, dessen Ersetzung in den jeweiligen Sprachdateien angegeben wird. Eine deutsche Sprachdatei könnte etwa so aussehen:</p>
<pre>
user_form_username=Benutzername
user_form_password=Password
</pre>
<p>Der Prefilter sucht also nach Sprachstrings und fügt an ihrer Stelle die entsprechende Ersetzung ein &#8211; je nachdem, welche Sprache eingestellt ist (z.B. in einer serverseitigen Konfigurationsdatei oder innerhalb der übermittelten Browserdaten des Clients usw.).</p>
<p>Für diese Funktionalität empfehle ich eine Klasse, die das Auslesen der Sprachdateien übernimmt. Der Einfachheit nenne ich sie &#8220;<em>Lang</em>&#8220;.</p>
<p>Ich muss aber darauf hinweisen, dass ich diese Klassen aus einem meiner eigenen Projekte entnommen habe. Daher kann es sein, dass ich teilweise vergessen habe, den Code an diesen Artikel anzupassen. Wenn also irgendetwas von &#8220;OBST&#8221; oder &#8220;XDB&#8221; dasteht, wisst ihr Bescheid. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Die Klasse <em>Lang</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
    <span style="color: #009933; font-style: italic;">/**
      * @author: Robert Nitsch
      */</span>
    <span style="color: #000000; font-weight: bold;">class</span> Lang <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$lng</span><span style="color: #339933;">;</span>
        protected <span style="color: #000088;">$lng_strings</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Lädt alle Sprachstrings aus der entsprechenden Sprachdatei.
          * @param string $lng Die Sprache, die geladen werden soll, als Länderkürzel.
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> load_lng<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lng</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lng</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lng</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">/* DIR_ROOT muss außerhalb dieser Datei deklariert werden und muss den Pfad
                 zum Hauptverzeichnis des Webprojekts beinhalten
                 Außerdem setzt diese Klasse eine gewisse Verzeichnisstruktur vorraus... (/include/lng) */</span>
            <span style="color: #000088;">$path</span> <span style="color: #339933;">=</span> DIR_ROOT<span style="color: #339933;">.</span><span style="color: #0000ff;">'/include/lng/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$lng</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.txt'</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$fh</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$matches</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$zeile</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fh</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^([^;\s]+)\s*=([^;]*).*$/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$zeile</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                    <span style="color: #009900;">&#123;</span>
                        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lng_strings</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #b1b100;">else</span>
            <span style="color: #009900;">&#123;</span>
                throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;language file '<span style="color: #006699; font-weight: bold;">$path</span>' doesnt exist&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Gibt einen Sprachstring zurück.
          * @param string $name Der Name des Sprachstrings.
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lng_strings</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     -&gt; singleton pattern
     (immer nur eine einzige Instanz dieser Klasse zulassen;
     Instanz(en) werden ausschließlich über diese Funktion erstellt)
    */</span>
    <span style="color: #000000; font-weight: bold;">function</span> getLangInstance<span style="color: #009900;">&#40;</span><span style="color: #000088;">$language</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        static <span style="color: #000088;">$lang_instance</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_object</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang_instance</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$obst</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$lang_instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Lang<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$lang_instance</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load_lng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$language</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$lang_instance</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Die angepasste Smarty-Klasse nenne ich <em>LangSmarty</em>. Dem Konstruktor muss natürlich eine Instanz der Klasse Lang übergeben werden. Alles Weitere steht in den Kommentaren.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
    <span style="color: #009933; font-style: italic;">/**
      * @author: Robert Nitsch
      */</span>
    <span style="color: #000000; font-weight: bold;">class</span> LangSmarty <span style="color: #000000; font-weight: bold;">extends</span> Smarty <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
            * Speichert die Instanz der Klasse Lang ab.
            * @var Lang Instanz der Klasse Lang
            */</span>
        protected <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Konstruktor
          * @param Lang $lang Eine Instanz der Klasse Lang, die die jeweiligen Sprachdaten beinhaltet.
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> LangSmarty<span style="color: #009900;">&#40;</span>Lang <span style="color: #339933;">&amp;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">// muss an das jeweilige Webprojekt angepasst werden</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">template_dir</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'./template_dir'</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">compile_dir</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'./compile_dir'</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache_dir</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'./cache_dir'</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">// den prefilter registrieren</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">register_prefilter</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'translate_prefilter'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Diese sogenannte Callback-Funktion wird für jedes Auftauchen von ##(...)## innerhalb von Templates
          * aufgerufen und gibt die jeweilige Ersetzung zurück.
          * @param string $string Die konkrete Übereinstimmung. Z.B. &quot;##user_form_username##&quot;
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> _translate_callback<span style="color: #009900;">&#40;</span><span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$string</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$string</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$string</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Dies ist der Smarty-Prefilter. Er führt die Ersetzung der Sprachstrings ##(...)##
          * durch die Callback-Funktion _translate_callback() durch.
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> translate_prefilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tpl_source</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$smarty</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">preg_replace_callback</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/##[^#]*##/&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'_translate_callback'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tpl_source</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
          * Jede sprache soll einen eigenen Satz an Compiled- und Cached-Files haben.
          * Dafür wird das jeweilige  Länderkürzel einfach in den Dateinamen dieser Dateien eingebaut.
          */</span>
        <span style="color: #000000; font-weight: bold;">function</span> fetch<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_smarty_tpl_file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_cache_id</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_compile_id</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_display</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #000088;">$_smarty_compile_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lang</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lng</span><span style="color: #339933;">.</span><span style="color: #000088;">$_smarty_compile_id</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$_smarty_cache_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_smarty_compile_id</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_smarty_tpl_file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_cache_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_compile_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_smarty_display</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Anwendung:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> getLangInstance<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'de'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// instanz der Lang-Klasse erstellen</span>
  <span style="color: #000088;">$smarty</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> LangSmarty<span style="color: #009900;">&#40;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// instanz der LangSmarty-Klasse erstellen, dem Konstruktor wird eine Lang-Instanz übergeben</span>
  <span style="color: #000088;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'startseite.tpl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// das Template startseite.tpl kompilieren und das Ergebnis dessen Ausführung (ja, bei Smarty werden Templates ausgeführt) an den Client schicken</span>
  <span style="color: #666666; font-style: italic;">// Sprachstrings werden automatisch eingefügt, sofern im Template vorhanden</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Das Ganze lässt sich aber noch optimieren. Die Lösung mit den oben gezeigten Sprachdateien ist zwar einfach, aber bei großen Projekten kann es in viel Arbeit ausarten alle Sprachdateien aktuell zu halten. Auch wenn man diese Arbeit an freiwillige Übersetzer delegieren kann, so empfiehlt es sich, das System generell zu verbessern.</p>
<p>Dies kann mit Hilfe von <a href="http://de.wikipedia.org/wiki/Gettext" rel="nofollow" class="liwikipedia">gettext</a> erreicht werden.</p>
<p>Zitat Wikipedia:</p>
<blockquote><p>GNU gettext ist die GNU-Internationalisierungsbibliothek. Normalerweise wird sie zur Entwicklung von mehrsprachigen Programmen genutzt. Die derzeit aktuelle Version ist 0.16.1.</p></blockquote>
<p>Und ja, auch in PHP kann man auf gettext zugreifen: <a href="http://de2.php.net/gettext" class="liphp">Gettext-Funktionen</a></p>
<p>Dank der objektorientieren Programmierung müssen wir nur die Klasse <em>Lang</em> an gettext anpassen. Das werde ich in diesem Artikel aber nicht mehr bis ins Detail erklären. Letztendlich läuft es darauf hinaus, dass man nur ein paar Zeilen verändert (nicht aber wesentliche Strukturen).</p>
<p>Der größte Aufwand steckt allerdings in der Gewöhnung an gettext. Bevor man auf gettext umsteigt, sollte man sich daher etwas einlesen. Mir hat der Text <a href="http://www.onlamp.com/pub/a/php/2002/06/13/php.html" class="liexternal">ONLamp.com &#8212; Gettext</a> sehr gefallen&#8230;</p>
<h3>Code herunterladen</h3>
<p>Es macht keinen Sinn, den Code direkt aus dem Beitrag herauszukopieren, da verschiedene Zeichen von WordPress ungünstig umgewandelt werden. Daher hier der Download des ZIP-Archivs mit den Klassen Lang und LangSmarty:</p>
<p><a href="http://www.robertnitsch.de/wp-content/uploads/2008/01/php-smarty-mehrsprachig.zip" title='Code herunterladen (Klassen Lang und LangSmarty)' class="lizip">PHP-Smarty-Mehrsprachig.zip herunterladen</a></p>
<p>Hinweis: Die Dateien sind UTF-8-kodiert. Linux-Benutzer werden damit keine Probleme haben, Windows-Nutzer sollten auf den <a href="http://notepad-plus.sourceforge.net/de/site.htm" class="liexternal">Notepad++ &#8211; Editor</a> zurückgreifen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/05/23/php-smarty-und-die-unterstutzung-mehrerer-sprachen-multilingualitat/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Python, das turtle-Modul und Fraktale</title>
		<link>http://www.robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/</link>
		<comments>http://www.robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/#comments</comments>
		<pubDate>Wed, 04 Apr 2007 09:54:02 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Informatik]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/</guid>
		<description><![CDATA[Ich hätte ja nicht gedacht, dass es so lustig sein kann, mit Fraktalen herumzuexperimentieren &#8230; aber das kann es doch. Ein bisschen Interesse natürlich vorrausgesetzt. Mit Hilfe des Lehrmaterials &#8220;Turtle-Grafik und Fraktale Geometrie&#8221; (http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522) konnte ich auch recht schnell einsteigen. Die Schilderungen und die Quelltexte sind auf das Modul turtle bezogen und sind somit grundsätzlich [...]]]></description>
			<content:encoded><![CDATA[<p>Ich hätte ja nicht gedacht, dass es so lustig sein kann, mit Fraktalen herumzuexperimentieren &#8230; aber das kann es doch. Ein bisschen Interesse natürlich vorrausgesetzt.</p>
<p>Mit Hilfe des Lehrmaterials &#8220;Turtle-Grafik und Fraktale Geometrie&#8221; (<a href="http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522" class="liexternal">http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522</a>) konnte ich auch recht schnell einsteigen. Die Schilderungen und die Quelltexte sind auf das Modul turtle bezogen und sind somit grundsätzlich plattformunabhängig. Dennoch empfehle ich Python für diese Experimente, denn dort ist das turtle-Modul bereits integriert und lässt sich phänomenal einfach verwenden.</p>
<h3>Das turtle-Modul</h3>
<p>Das turtle-Modul ist eine Sammlung an Funktionen, mit deren Hilfe sich ein &#8220;Malstift&#8221; bzw. &#8220;turtle&#8221; steuern lässt. Mit Anweisungen wie left(), right(), forward() und backward() kann man einfachste Bewegungen koordinieren. Packt man derartige Anweisungen in rekursive Funktionen, so ergibt sich mit etwas Glück ein immerwiederkehrendes selbstähnliches Gebilde &#8211; ein Fraktal.</p>
<p>Die Dokumentation des pythoneigenen turtle-Moduls ist hier zu finden:</p>
<p><a href="http://docs.python.org/lib/module-turtle.html" class="liexternal">http://docs.python.org/lib/module-turtle.html</a></p>
<h3>Die Kochkurve</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># coding=UTF-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">turtle</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> kochkurve<span style="color: black;">&#40;</span>t, s<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>t==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># wenn die gewünschte rekursionstiefe (sprich: feinheit der bewegungen) erreich ist,</span>
        <span style="color: #808080; font-style: italic;"># soll das ganze auf dem bildschirm umgesetzt werden</span>
        forward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #808080; font-style: italic;"># die bewegungen der &quot;turtle&quot; werden rekursiv verfeinert</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">120</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span>
        kochkurve<span style="color: black;">&#40;</span>t-<span style="color: #ff4500;">1</span>, s/<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># koch'sche schneeflocke, zusammengesetzt aus mehreren kochkurven</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
left<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">90</span><span style="color: black;">&#41;</span>
color<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
kochkurve<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># die methode done(), die die hauptschleife betritt, ist offenbar nicht verfügbar :-(</span>
<span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
done<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<hr />
<p>Die Rekursionstiefe (t) bestimmt die Feinheit der Bewegungen. Der Parameter s definiert die Gesamtlänge der Kochkurve.</p>
<p>Ich habe die Funktion am Ende mehrfach aufgerufen, sodass eine sogenannte Koch&#8217;sche Schneeflocke entsteht. Eine Koch&#8217;sche Schneeflockte besteht aus mehreren Kochkurven, die man aneinandergehängt hat. Und hängt man 4 Kochkurven im Winkel von 90° aneinander, so ergibt sich folgendes Gebilde:</p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/04/kochsche_schneeflocke.jpg" title='Koch’sche Schneeflocke' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/04/kochsche_schneeflocke.jpg' alt='Koch’sche Schneeflocke' /></a></p>
<h3>Der fraktale Baum</h3>
<p>Fraktale Bäume haben mich irgendwie schon immer beschäftigt. Man stelle sich einen Körper vor, von dem etliche Zweige und Äste abgehen. Von jedem Zweig und jedem Ast gehen erneut ebensoviele Zweige und Äste ab &#8211; diesmal nur wesentlich kleiner. Und von diesen kleinen Ästen gehen wieder Äste ab &#8230; immer wieder &#8230; und jedes Mal werden sie kleiner. Ich hatte meinen Spaß daran mir den kleinsten denkbaren Ast vorzustellen. Natürlich hatte dieser Gedankengang nie ein Ende. Aber wenn man jung ist&#8230; <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Mit dem turtle-Modul lassen sich natürlich auch fraktale Bäume erzeugen.</p>
<p>Z.Bsp. hiermit:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># coding=UTF-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">turtle</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> baum<span style="color: black;">&#40;</span>s,t<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>t <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        forward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span>
        baum<span style="color: black;">&#40;</span>s<span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.6</span>, t-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        right<span style="color: black;">&#40;</span><span style="color: #ff4500;">75</span><span style="color: black;">&#41;</span>
        baum<span style="color: black;">&#40;</span>s<span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.7</span>, t-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        left<span style="color: black;">&#40;</span><span style="color: #ff4500;">45</span><span style="color: black;">&#41;</span>
        backward<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
sety<span style="color: black;">&#40;</span>-<span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
baum<span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>,<span style="color: #ff4500;">7</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># die methode done(), die die hauptschleife betritt, ist offenbar nicht verfügbar :-(</span>
<span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
done<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<hr />
<p>Mit Hilfe des Parameters t lässt sich auch hier die Rekursionstiefe festlegen.</p>
<p>Der Code ergibt, wenn man ihn mit dem Python-Compiler aufruft, folgendes:</p>
<p><a href="http://robertnitsch.de/wp-content/uploads/2007/04/fraktaler_baum_klein.jpg" title='Fraktaler Baum' class="liimagelink"><img src='http://robertnitsch.de/wp-content/uploads/2007/04/fraktaler_baum_klein.jpg' alt='Fraktaler Baum' /></a></p>
<p>Selbstverständlich lassen sich Winkel und Streckenlängen variieren. In diesem konkreten Fall ist der linke Ast um 30° (nach links), der rechte um 45° (nach rechts) abgewinkelt. Der linke Ast hat die Länge 0,6*s &#8211; das entspricht 60% der Länge des Mutterastes. Der rechte Ast hat jeweils die Länge 0,7*s &#8211; also 70% der Länge des Mutterastes.</p>
<h3>Weitere Anregungen</h3>
<p><a href="http://www.herr-rau.de/wordpress/2007/03/meine-erste-fischpopulation.htm" class="liexternal">Fischpopulationen im Lehrerzimmer</a> mit Tkinter (kleine Andeutung am Rande <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>
<p><a href="http://miami.uni-muenster.de/servlets/DocumentServlet?id=1522" class="liexternal">Turtle-Grafik und fraktale Geometrie</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/04/04/python-das-turtle-modul-und-fraktale/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress mit .htaccess absichern</title>
		<link>http://www.robertnitsch.de/2007/01/18/wordpress-mit-htaccess-absichern/</link>
		<comments>http://www.robertnitsch.de/2007/01/18/wordpress-mit-htaccess-absichern/#comments</comments>
		<pubDate>Thu, 18 Jan 2007 14:44:49 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Webmaster]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://robertnitsch.de/2007/01/18/wordpress-mit-htaccess-absichern/</guid>
		<description><![CDATA[Inhalt: Nutzen /wp-admin passwortschützen Absoluten Serverpfad ermitteln Benutzerdatei anlegen Passwörter verschlüsseln Benutzerdatei fertigstellen /wp-include Ordner schützen Abschließende Hinweise Weblinks Dieser Eintrag handelt von WordPress. Genauer gesagt geht es darum WordPress mit sogenannten .htaccess-Dateien abzusichern. .htaccess-Dateien können allerlei Regeln beinhalten, die bestimmen wie mit Dateianfragen umgegangen werden soll. Es gibt viele Beispiele, was man mit .htaccess [...]]]></description>
			<content:encoded><![CDATA[<p>Inhalt:</p>
<ul>
<li>Nutzen</li>
<li>/wp-admin passwortschützen</li>
<li>Absoluten Serverpfad ermitteln</li>
<li>Benutzerdatei anlegen</li>
<li>Passwörter verschlüsseln</li>
<li>Benutzerdatei fertigstellen</li>
<li>/wp-include Ordner schützen</li>
<li>Abschließende Hinweise</li>
<li>Weblinks</li>
</ul>
<p>Dieser Eintrag handelt von WordPress. Genauer gesagt geht es darum WordPress mit sogenannten .htaccess-Dateien abzusichern. .htaccess-Dateien können allerlei Regeln beinhalten, die bestimmen wie mit Dateianfragen umgegangen werden soll. Es gibt viele Beispiele, was man mit .htaccess alles anstellen kann, z.B.:</p>
<p>- Verzeichnisse für bestimmte IPs, IP-Bereiche oder für jeden zu sperren<br />
- Verzeichnisse mit einem Passwort schützen (es können <em>mehrere</em> Benutzernamen definiert werden, mit denen man zugreifen darf!)<br />
- alle diese Regeln können natürlich auch auf bestimmte Ordner/Dateien begrenzt werden</p>
<p>Uns geht es aber hauptsächlich darum,</p>
<p>- das /wp-admin Verzeichnis mit einem Passwortschutz zu versehen. Doppelter Schutz!<br />
- das /wp-include Verzeichnis für den Zugriff von außen komplett zu sperren (nur .php-Dateien sollen gesperrt werden)</p>
<h3>Nutzen:</h3>
<p>Damit kann man einem &#8220;bösartigen&#8221; Besucher das &#8220;Leben&#8221; durchaus erschweren. Denn: ohne Zugriff auf den /wp-admin Ordner bekommt man nicht mal den normalen Admin-Login von WordPress zu Gesicht. Falls es also Sicherheitslücken im Loginskript gibt, so ist man aufs Erste geschützt, auch ohne sofort ein Update einspielen zu müssen (was man natürlich trotzdem tun sollte!!). An den Login kommt man ja nur durch einen vorherigen Login heran (.htaccess ist bereits seit vielen Jahren erprobt und gilt als sehr sicher &#8211; im Gegensatz zu den meisten PHP-Skripts). <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Das /wp-include Verzeichnis ist für den normalen Benutzer sowieso nicht von Bedeutung. Es gibt aber durchaus Techniken, mit denen ein &#8220;Hacker&#8221; Sicherheitslücken innerhalb der .php-Dateien in diesem Verzeichnis aufspüren und ggf. ausnutzen kann. Wir verbieten aber gleich sofort den gesamten Zugriff und schließen damit weitere Sicherheitslücken aus.</p>
<h3>/wp-admin passwortschützen:</h3>
<p>Jetzt wollen wir mal loslegen. Zuerst müssen wir das /wp-admin Verzeichnis mit einem Passwort versehen. Dazu erstellen wir eine Datei mit dem Namen .htaccess und folgendem Inhalt:</p>
<blockquote><p>AuthType Basic<br />
AuthName &#8220;WordPress Administration&#8221;<br />
AuthUserFile  /absoluter/serverpfad/zurbenutzerdatei/.htaccess_wordpress<br />
require valid-user</p></blockquote>
<p>Diese Datei muss jetzt in das /wp-admin Verzeichnis hochgeladen werden.</p>
<p><em>Erklärung:</em><br />
In der ersten Zeile wird der Passwortschutz &#8220;eingeleitet&#8221;. In der zweiten Zeile wird dem geschützten Bereich ein Name gegeben. Die dritte Zeile ist <strong>wichtig!</strong> Hier muss der <em>absolute (Server-)Pfad</em> zur <em>Benutzerdatei</em> angegeben werden.</p>
<h3>Absoluten Serverpfad ermitteln:</h3>
<p>Der <em>absolute Serverpfad</em> kann relativ leicht ermittelt werden. Man muss eine Datei mit dem Namen pfad.php und folgendem Inhalt erstellen, in das WordPress-Verzeichnis hochladen und dann mit dem Browser aufrufen:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Der absolute Pfad zu diesem Verzeichnis ist: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<h3>Benutzerdatei anlegen:</h3>
<p>Die <em>Benutzerdatei</em> sollte man in ein Verzeichnis legen, das nicht über die Domain zugreifbar ist. Am besten wäre das Verzeichnis, das eine Ebene über der WordPress-Installation liegt. Noch besser wäre das &#8220;allerhöchste&#8221; Verzeichnis.</p>
<p>Die <em>Benutzerdatei</em> beinhaltet alle Benutzer mit den dazugehörigen Passwörtern. Das Schema für ihren Inhalt lautet folgendermaßen:</p>
<blockquote><p>benutzername:passwort<br />
hans:nadine1987<br />
joerg:petra1976</p></blockquote>
<p>(Die Passwörter, die hier beispielhaft gezeigt werden, sind natürlich keine Musterpasswörter. Sie sind weit davon entfernt, sicher zu sein.)</p>
<p>Also pro Zeile ein Benutzer. Benutzer und Passwort werden durch einen Doppelpunkt getrennt.</p>
<h3>Passwörter verschlüsseln:</h3>
<p>Es fällt außerdem sofort auf, dass die Passwörter hier im Klartext lesbar sind. Gelingt es einem Hacker doch einmal, den Webspace oder den ganzen Server zu hacken, so wird er auch an diese Passwörter gelangen. Das kann man jedoch mit einer sogenannten <em>Einweg-Verschlüsselung</em> unterbinden.</p>
<p>Dazu benötigen wir noch ein Skript mit dem Namen crypt.php und diesem Inhalt:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$text</span><span style="color: #339933;">=</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'crypt('</span><span style="color: #339933;">.</span><span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">') = '</span><span style="color: #339933;">.</span><span style="color: #990000;">crypt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'This script encrypts strings with the crypt()-function. e.g.: &quot;crypt.php?text=&lt;thestringyouwanttoencrypt&gt;&quot;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&amp;copy; www.robertnitsch.de'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Dieses Skript kann dann ebenfalls auf den Webspace hochgeladen und über den Browser aufgerufen werden. Zum Beispiel wird http://www.domain.tld/wordpress/crypt.php?text=test den verschlüsselten Wert von &#8220;test&#8221;  berechnen. Dieser sieht zum Beispiel so aus:</p>
<p><strong>$1$Udvw2Yfc$XGUZ6EZFvTC/.9r9.99yX1</strong></p>
<p>Offensichtlich ist das ganz schönes Kauderwelsch. Diese Verschlüsselung kann man auch nicht rückgängig machen.</p>
<p>Wir tragen die verschlüsselten Passwörter genauso ein wie die nicht verschlüsselten, z.B.:</p>
<blockquote><p>test-user:$1$Udvw2Yfc$XGUZ6EZFvTC/.9r9.99yX1</p></blockquote>
<p>Auf diese Weise ist auch unsere Benutzerdatei einigermaßen sicher.<br />
<em>Hinweis:</em><br />
Das Mischen von verschlüsselten und nicht verschlüsselten Passwörtern in derselben Benutzerdatei ist nicht möglich. Entweder es sind alle Passwörter verschlüsselt oder gar keines.</p>
<h3>Benutzerdatei fertigstellen:</h3>
<p>Die Benutzerdatei muss jetzt noch angelegt werden &#8211; wir waren ja wegen der Verschlüsselung noch nicht soweit. Der Dateiname sollte .htaccess_wordpress sein. Wie bereits beschrieben müssen die Benutzernamen und jeweils mit einem Doppelpunkt davon getrennt die Passwörter eingetragen werden. Unbedingt vorher mit <strong>crypt</strong> verschlüsseln (wie oben beschrieben)! Der absolute Pfad zu der Benutzerdatei musst jetzt noch in der .htaccess-Datei eingetragen werden &#8211; falls noch nicht geschehen. Ggf. müssen wir die .htaccess-Datei neu hochladen, damit die Änderung des absoluten Pfades überhaupt wirksam werden kann.</p>
<p>Ab jetzt sollte bei jedem Zugriff auf das /wp-admin Verzeichnis eine Passwortabfrage erscheinen. Wenn alles klappt, dann fahren wir jetzt mit dem Absichern des /wp-include Verzeichnisses fort.</p>
<h3>/wp-include Ordner schützen:</h3>
<p>Wir erstellen eine weitere Datei &#8220;.htaccess&#8221; mit dem folgenden Inhalt:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># alle PHP-Dateien fuer den Zugriff von außen sperren</span>
&lt;<span style="color: #000000; font-weight:bold;">FilesMatch</span> \.php$&gt;
<span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
<span style="color: #00007f;">deny</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">all</span>
&lt;/<span style="color: #000000; font-weight:bold;">FilesMatch</span>&gt;
&nbsp;
<span style="color: #adadad; font-style: italic;"># tinymce (der what-you-see-is-what-you-get-editor beim schreiben von eintraegen)</span>
<span style="color: #adadad; font-style: italic;"># muss zugaenglich sein</span>
&lt;<span style="color: #000000; font-weight:bold;">FilesMatch</span> ^tiny_mce&gt;
<span style="color: #00007f;">allow</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">all</span>
&lt;/<span style="color: #000000; font-weight:bold;">FilesMatch</span>&gt;
&lt;<span style="color: #000000; font-weight:bold;">FilesMatch</span> ^wp\-mce&gt;
<span style="color: #00007f;">allow</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">all</span>
&lt;/<span style="color: #000000; font-weight:bold;">FilesMatch</span>&gt;</pre></div></div>

<p>Wir speichern diese Datei im /wp-include Verzeichnis. Danach ist auch dieses Verzeichnis sicher und wir sind eigentlich fertig.</p>
<h3>Abschließende Hinweise:</h3>
<p>Bei manchen Anbietern sind diverse Funktionen von .htaccess nicht verfügbar oder gesperrt. In diesem Fall wird ein &#8220;Internal Server Error&#8221; mit dem Fehlercode 500 auftreten.<br />
Wenn Syntaxfehler oder ähnliche Fehler in den .htaccess-Dateien vorhanden sind, dann wird beim Zugriff auf das entsprechende Verzeichnis bzw. auf die entsprechende Datei ebenfalls ein &#8220;Internal Server Error&#8221; mit dem Fehlercode 500 auftreten.<br />
Falls unerwartete Probleme auftreten könnt ihr gerne die Kommentar-Funktion nutzen und somit Hilfe einholen. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Wenn etwas partout nicht funktionieren will kann die .htaccess-Datei problemlos wieder vom Webspace entfernt werden. Die Regeln werden damit sofort außer Kraft gesetzt. (Möglicherweise müsst ihr noch euren Browsercache leeren!)</p>
<h3>Weblinks:</h3>
<p>SelfHTML: <a href="http://de.selfhtml.org/servercgi/server/htaccess.htm" class="liexternal">.htaccess &#8211; Server-Reaktionen kontrollieren</a><br />
PC-Projekt: <a href="http://pc-projekt.net/showthread.php?tid=81&#038;pid=431#pid431" class="liexternal">.htaccess &#8211; Dateien einsetzen</a><br />
SoftwareGuide: <a href="http://sw-guide.de/webdesign-und-entwicklung/htaccess-mod_rewrite-fuer-cms-und-blog/" class="liexternal">.htaccess und Mod-Rewrite für CMS und Blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/01/18/wordpress-mit-htaccess-absichern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.htaccess &#8211; Tutorial</title>
		<link>http://www.robertnitsch.de/2007/01/09/htaccess-tutorial/</link>
		<comments>http://www.robertnitsch.de/2007/01/09/htaccess-tutorial/#comments</comments>
		<pubDate>Tue, 09 Jan 2007 16:58:54 +0000</pubDate>
		<dc:creator>Robert</dc:creator>
				<category><![CDATA[PC]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Webmaster]]></category>

		<guid isPermaLink="false">http://robertnitsch.de/2007/01/09/htaccess-tutorial/</guid>
		<description><![CDATA[Ich habe gerade ein sehr ausführliches Tutorial zum Thema .htaccess-Dateien geschrieben. Ihr könnt es hier ansehen: http://www.pc-projekt.net/showthread.php?tid=81&#038;pid=431#pid431 Eine Registrierung in diesem Forum lohnt sich bestimmt. UPDATE: Besagtes Forum ist mittlerweile geschlossen und der Link deswegen nicht mehr gültig. Das Tutorial behandelt folgende Themen: - Verzeichnis komplett sperren - Passwortschutz - Regeln auf einzelne Dateien beschränken [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe gerade ein sehr ausführliches Tutorial zum Thema .htaccess-Dateien geschrieben. Ihr könnt es hier ansehen: <a href="http://www.pc-projekt.net/showthread.php?tid=81&#038;pid=431#pid431" title="http://www.pc-projekt.net/showthread.php?tid=81&#038;pid=431#pid431" class="liexternal">http://www.pc-projekt.net/showthread.php?tid=81&#038;pid=431#pid431</a><br />
Eine Registrierung in diesem Forum lohnt sich bestimmt. <img src='http://www.robertnitsch.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>UPDATE:</strong> Besagtes Forum ist mittlerweile geschlossen und der Link deswegen nicht mehr gültig.</p>
<p>Das Tutorial behandelt folgende Themen:</p>
<p>- Verzeichnis komplett sperren<br />
- Passwortschutz<br />
- Regeln auf einzelne Dateien beschränken<br />
- Eigene Fehlerseiten</p>
<p>Ich bin mir sicher, dass das für den einen oder anderen interessant sein könnte.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robertnitsch.de/2007/01/09/htaccess-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
