Freitag, 28. November 2008

XML in Farbe und bunt

Wer Latex verwendet, ist ein wenig verwöhnt, was das Einfügen von XML betrifft - Syntax Highlighting inklusive:
...
\usepackage{listings}
...
\lstset{
language=XML
}
\begin{lstlisting}
% XML Quelltext ...
\end{lstlisting}
Mit einem kleinen Trick erzielt man den gleichen Effekt auch in gewohnten Textverarbeitungsprogrammen à la Word und OpenOffice Writer: XML Dokument in Eclipse öffnen, per Copy und Paste ins Textdokument einfügen - fertig!

Mittwoch, 26. November 2008

A4: XPath - Kopfweh inklusive, eine bittere Wahrheit

Mein Modell habe ich bereits in einem früheren Blog-Eintrag vorgestellt. Meine dazugehörigen XPath Abfragen sind die folgenden (in der Realität auch tatsächlich gestellten Fragen):
  • Zu welchen Tumoren wurde noch kein Krebsmeldeblatt angelegt? (Eigentlich wollte ich folgendes abfragen: Zu welchen Erst- und Zweit-Tumoren wurde noch kein Krebsmeldeblatt angelegt? Warum das nicht geht, seht ihr wenn die Scrollleiste am unteren Browserrand ansteht) - Ärzte sind verpflichtet bei allen neu aufgetretenen Tumoren (Also Erst-,Zweittumoren, nicht aber Rezidive oder Residuen) ein Krebsmeldeblatt an das Krebsmelderegister der Statistik Austria zu senden.
  • Untersuchungen, bei denen ein Residuum entdeckt wurde (Da hat dann der Chirurg zu wenig weggeschnibbelt)
  • Die Ausdehnung aller benignen Tumoren des Patienten mit der SVNR 1234010155 (knifflig!)
Schon bei Anfrage 3 werde ich etwas stutzig - die XML Arbeitsumgebung markiert das ResultSet nicht wie gewohnt rot.

Weiter gings mit Teil 2 - XPath Abfragen für das Regierungs-Modell. Auf der verzweifelten Suche nach *sinnvollen* Abfragen fallen mir allzu banale und einige anspruchsvollere ein. Mit Hilfe der "Evaluate XPath" Funktion im XML Spy (der die Abfragen live beim Tippen aktualisiert und so auf dem Lösungsweg unterstützt) sind bald alle fertig formuliert - doch die XML Arbeitsumgebung hält einen Teil davon für ungültig. Es kommen leichte Zweifel auf: propriätäre Funktionen von XML Spy? Nein, die W3C XPath Recommendation enthält sie ebenfalls. Also schnell ein paar ganz simple Abfragen testen: number(), current-date(), ... und siehe da: denkste! Die Arbeitsumgebung wird doch nicht ...

Ein paar Tests in Xalan und Saxon später: Xalan verweigert seinen Dienst, Saxon liefert genau das erwartete Ergebnis. Jetzt noch schnell am Almighty einloggen und "env" tippen - sofort sticht "CLASSPATH= (...) /opt/Axis/lib/xercesImpl.jar" ins Auge. Xalan baut auf Xerces auf, und unterstützt nur XPath 1 - das gilt dann auch für das Frontend in der Arbeitsumgebung.

Schade :(

Freitag, 21. November 2008

The Power of J2EE + Richfaces - oder: Wer hat den kürzeren?

Michael Derntl hat vor wenigen Tagen berichtet, wie er sich mit Hilfe von Bibliotheken (Prototype) das Leben einfacher macht. Das selbst gesetzte Ziel war es, den nötigen selbsterstellten Quelltext von AJAX Applilkationen zu verkürzen - ganz nach dem Motto "Code less, create more".

Ich behaupte frech, es geht noch viel einfacher und trete gleich den Beweis an. Unterstützen lasse ich mich dabei von JBoss RichFaces, einer JSF Implementierung mit AJAX Out-of-the-Box Support.

Der Taschenrechner wäre mit folgendem Code erledigt:
<h1>AJAX Calculator Demo</h1><a4j:form>
Multiply <h:inputText value="#{calculator.x}" /> x <h:inputText value="#{calculator.y}" />
<a4j:commandButton value="=" action="#{calculator.calc}" reRender="result" />
<b><h:span id="result">#{calculator.result}</h:span></b>
</a4j:form>

public class Calculator
{
private int x,y,result;
public int getX() { return x; }
public int getY() { return y; }
public int getResult() { return result; }
public void setX(x) { this.x = x; }
public void setY(y) { this.y = y; }
public void calc() { result = x*y; }
}

Das Beispiel zum Bearbeiten von Texten sobald man draufklickt, reduziert sich überhaupt auf eine einzige Zeile:
<rich:inplaceInput value="#{bean.text}" />
Wers nicht glaubt, oder live ausprobieren mag, kann sich Demos zum A4J CommandButton und zum Rich InplaceInput anschauen.

Was lernen wir daraus? Mit den richtigen Frameworks und Bibliotheken hat man mehr Zeit für wichtige Dinge. Software entwickeln statt Programmieren. Held der Arbeit statt Coding Monkey.

Donnerstag, 20. November 2008

A3: XML / DTD

Nachdems anlässlich des von David Selig veröffentlichten Klassendiagramms keine Beschwerden gegeben hat, tue ich es ihm hiermit gleich. Damit erspare ich mir einen zweiten Post nach der Deadline zur gleichen Aufgabe, außerdem schätze ich mein Thema als exotisch genug ein um anderen nicht in die Quere zu kommen. Ich habe wieder einmal mein Faible für die Medizin ausgelebt und ein Mini-Tumordokumentationssystem abgebildet:


Hintergrundinformation

Patienten werden erst dann erfasst, wenn sie einen Tumor haben. Diese Tatsache spiegelt sich in den Kardinalitäten der Beziehung zwischen Patient (1) und Tumor (N, jedoch mindestens 1) wieder.

Ein Tumor wird eindeutig identifiziert durch die Lage und die Differenzierung. Die Lage wird angegeben durch einen obligatorischen Organbezirk (zB Nasenhaupthöhle) und gegebenenfalls eine Organseite (Links, Rechts, Mitte, oder Keine Seite wenn anatomisch auch keine vorhanden ist). Die Differenzierung ist ist die histologische Einteilung in benign, malign, semimalign oder undifferenziert. Zwei vollständige Beispiele wären also „Nasenhaupthöhle Rechts malign“ und „Zungenspitze Mitte benign“.

Zu jedem Tumor kann ein Krebsmeldeblatt zur Einsendung an das Krebsmelderegister der Statistik Austria angelegt werden, muss aber nicht.

Im Rahmen der Untersuchungen eines Patienten werden allgemeine Anamnese-Daten erfasst, etwa das Gewicht und Tumor unspezifische Begleiterkrankungen (Hypertonie, Diabetes, ...). Bei jeder Untersuchung werden entweder alle oder nur ein Teil der Tumoren genau untersucht. Dabei werden der Tumorstatus (Ersttumor, Zweittumor, Rezidiv, Residuum) seine Ausdehnung (befallene Organbezirke), sowie spezifische Krankheitssymptome und Nervenläsionen erfasst.

In der Praxis werden unter anderem auch noch eingesetzte Diagnoseverfahren (zB Bildgebung [Röntgen, PET, Szintigraphie, ...], Endoskopie, Gewebsentnahme/Histologie) und Therapien
(Chemotherapie, Radiotherapie, Kombitherapie, Operation, Sonstige Verfahren) dokumentiert, in diesem Modell jedoch nicht abgebildet.

Das DTD ...

... veröffentliche ich natürlich nicht :p

Als viel beschäftigter Mensch bin ich natürlich interessiert, mir möglichst wenig Arbeit zu machen und die unvermeidbaren Dinge möglichst effizient zu lösen. Darum habe ich ein wenig geschummelt und die Anweisung von oben, "Erstellen Sie zur DTD ein XML Dokument" missachtet. Am Anfang war das XML, und das XML war bei XMLSpy, und bei XMLSpy ward das DTD.

Damits nicht ganz so billig ist, gabs danach einen Handarbeits-Feinschliff: ID und IDREF wurden genutzt, das Gewicht hat eine FIXED Einheit ("kg") und zu guter Letzt gab es noch Enumerierungen für die Organseite (links|rechts|mitte|keine) sowie Differenzierung (benign|malign|semimalign|undifferenziert|unbekannt).

Jetzt müssen höhere Mächte nur noch die XML Arbeitsumgebung reanimieren (Command env not found!), damit ich das ganze fertig abgeben kann.

Dienstag, 18. November 2008

P [3,4]: Review

Der furchtlose Kollege Klaffenböck aus Team 2 hat hier [1] und hier [2] Entwürfe seines Komponentendiagramms vorgestellt.

Was mich dabei am Entwurf [1] stört:

  • "Userprofil anzeigen / erstellen / bearbeiten" sind Anwendungsfälle, (imho) keine Komponenten
  • Ebenso die anderen Layer 1 - "Komponenten"
Ad [2]:

  • Folie 2: Bearbeiten und Kommentieren sind Anwendungsfälle, mit dem Rest kann ich leben wenn ich es mir richtig interpretiere
Das zieht sich eigentlich durch die meisten Diagramme, und auch der folgende Blogeintrag vermittelt mir irgendwie das Gefühl, dass aus etwas das sinnvollerweise ein Klassendiagramm bzw. Usecase-Diagramm sein sollte, krampfhaft in "Komponenten" gezwängt wird, siehe auch:

(...) darauf praktisch die Inhalte unseres letzten UML-Diagramms abbilden, also "was kann ich mit dem System alles machen?", denn das beschreibt ja meiner Meinung nach die logischen Funktionen
Bei Architektur und Komponenten denke ich da viel mehr ans ganz Grobe, bzw. an die Struktur des Projekts im Filesystem (bzw. das logische Mapping dann dazu, die Java Packages).

Sinnvolle Komponenten könnten dann meiner Meinung nach sein: Java Packages, Verzeichnisse, Bibliotheken (zb Hibernate/PDO/JDBC für den DB-Zugriff --> Komponente Datenbankanbindung), ...

Genau aus diesem Grund ist unser Entwurf auch sehr generisch (er könnte eigentlich für jedes beliebige Projekt genommen werden) und beinhaltet auch keine explizit erwähnten Klassen (wie zB "Prüfung", "Lehrveranstaltung", "Hörsaal", "Prüfungsanmeldung", "Prüfungsergebnis") - all diese Klassen würden meiner Meinung nach dann in ein Klassendiagramm kommen, dass deren Attribute und Beziehungen abbildet - fürs Komponentendiagramm sollte ihr gemeinsamer "Übervater" Entity bzw. Model als Paket bzw. Komponente bestens passen.

Hm ja... Schlafenszeit :p

P3: Architektur

Zugegebenermaßen, ich habe mich die letzten paar Tage nicht mit dem Blog beschäftigt (weder dem eigenen noch jenen der anderen Kollegen aus SWA) . Erst jetzt nach der Abgabe von P3, bemerkte ich dass wir eigentlich etwas gezeichnet haben, dass sich von den anderen Entwürfen sehr stark unterscheidet.

Im nächsten Eintrag werde ich dann einen Review zur Architektur von Team 2 aus Gruppe 4 posten, und damit auch ein wenig begründen warum unser Diagramm so anders ist.

Da die Deadline ohnehin schon vorbei ist, stelle ich hier einmal unsere Variante vor, wobei die Erläuterungen aus der Abgabe 1:1 kopiert sind.



Das System verwendet das Presentation-Abstraction-Control Pattern für seine grundlegende Architektur. Im Groben orientiert sich diese an den Ideen des JBoss Seam Frameworks.

Der Presentation Layer wird dabei von einem Pull-basiertem Template-System und einer Presenter-Klasse gebildet, die die PHP Objekte on Demand zur Verfügung stellt und für den Pageflow sowie Fehler- und Erfolgsmeldungen verantwortlich ist. Die Zuordnung zwischen Template-Variable und Backing Bean dabei über den Klassennamen bzw. Attributsnamen. Das Importieren von Objekten erfolgt dabei über Schnittstellen zur Cotrol Komponente.

Der Control Layer übernimmt die Steuerung der Webanwendung und verbindet die beiden anderen Layer Abstraction und Presentation. Zentraler Einstiegspunkt ist der Front Controller mit integriertem Request Dispatcher. Bei jedem HTTP Request wird die korrespondierende Methode der Anwendungslogik aufgerufen, und benötigte Request Parameter als Argumente übergeben. Zur Entkopplung "echter Business-Logik" und Web-Programmierung bietet dieser Layer auch Schnittstellen für Authentifizierung, Rechtemanagement, und Verwaltung der Session.

Der Application Layer ist für die eigentliche Business-Logik zuständig. Die "Application Logic" Komponente beinhaltet dabei alle Klassen zur Umsetzung der funktionalen Anforderungen, deren Methoden sind die Implementierung von Anwendungsfällen und werden vom Front Controller gestartet.

Das Objektmodell wird im Subsystem Model realisiert. Im Paket "Entity" befinden sich (analog zu POJOs) die Klassen zur Abbildung der Realität mit entsprechenden Attributen und dazugehörigen gettern und settern. Diese können von der Applikationslogik über eine Factory instanziert werden. Der Persistence Manager übernimmt das Laden und Speichern der Objekte im gewünschten Persistenzsystem, also zB einer relationalen Datenbank oder XML-Dateien. Die dafür benötigten Meta-Informationen (Spaltennamen, ...) werden dabei entweder über Konvention (Klassenname == Tabellenname, Attributname == Spaltenname, ...) oder Annotationen festgelegt.

<?php echo "intim" ?>

Ob der Titel wohl wieder dazu führt, dass ein weiterer SWA-Blog als Spamblog oder als nicht jugendfreier Blog eingestuft wird?

Dieser Eintrag stellt eine Premiere in meinem Blog dar: es ist der erste ganz ohne jeden Bezug zu einer Aufgabe.

In einem SWA Foren-Eintrag wurde einmal der Ratschlag gegeben, die einfachen Hochkommas beim Echo durch doppelte zu ersetzen.

In den meisten Fällen wird das gemacht, wenn man im echo-Text nochmals einfache oder doppelte Hochkommas ausgeben will. Wo aber liegt der Unterschied?

Strings unter einfachem Hochkomma werden von PHP nicht weiter geparst, sondern "raw" ausgegeben, solche unter doppeltem Hochkomma erst ausgewertet.

Beispiel:

$a=1;
echo '$a'; //Ausgabe: $a
echo "$a"; //Ausgabe: 1

Übrigens: echo ist keine Funktion! Unkreativerweise zitiere ich hier nur das offizielle PHP Manual:

echo() ist nicht wirklich eine Funktion sondern ein Sprach-Konstrukt, daher brauchen Sie keine Klammern verwenden. echo() verhält sich im Gegensatz zu einigen anderen Sprach-Konstrukten nicht wie eine Funktion, deshalb kann es nicht immer in einem Funktionskontext verwendet werden. Hinzu kommt, dass bei der Angabe mehrerer Parameter für echo() diese nicht von Klammern umschlossen sein dürfen.

Das hat eine besondere Auswirkung: die beiden folgenden Statements produzieren die gleiche Ausgabe, intern gibt es aber Unterschiede.

echo 'A'.'B'.'C'.'D';
echo 'A','B','C','D';

Einmal verwende ich also Punkte, dabei wird der String zusammengesetzt (A... AB... ABC... ABCD...) und erst dann ausgegeben (bzw. genau genommen eigentlich in den Output Buffer geschrieben).

Beim zweiten Mal verwende ich Kommas, dabei wird jeder Teil sofort ausgegeben. Das erspart Zeit und Speicher.

Möglich ist das wie gesagt nur deshalb, weil echo keine Funktion, sondern ein Konstrukt ist. Natürlich wird $a = 'a','b','c'; im Gegensatz zu $a = 'a'.'b'.'c'; NICHT funktionieren.

Draufgekommen bin über Umwege ich im Rahmen eines Seminars, bei dem ich PHP Obfuscator Software untersucht habe. Einige dieser Produkte produzieren "Bytecode" (eigentlich einen PHO Operation Cache), mit bcompiler kann man diesen dann aber "disassemblieren". Bei der Analyse einiger Skripte ist mir dieser Unterschied dann aufgefallen.

A2: So schnell können drei Wochen vergehen

Es war einmal vor langer Zeit, da gab es eine Vorschau auf die zweite Einzelaufgabe. Einen halben Tag später war die geforderte Funktionalität auch schon implementiert.

Dann kamen noch zwei weitere Aufgaben für Interssierte dazu, wovon ich die zweite auch bald danach umgesetzt habe. Die eigentlich einfachere erste Fleißaufgabe wollte ich dann später noch machen. Aus später wurde aber zu spät, und so fiel sie ins Wasser.

Trotzdem gibt es hier noch ein paar Gedanken und Hints dazu...

Teil 1: Files

Soweit so gut, oder auch nicht - File Uploads stellen eine gefährliche Quelle für Sicherheitslücken dar. Wer ein Bild erwartet, der sollte sicherstellen, dass auch tatsächlich ein Bild hochgeladen wurde. Sonst kann es auch sein, dass eine "Bildergallerie" plötzlich als Ablage für Warez-Archive dient (auch wenn diese Zeit seit P2P mehr oder weniger vorbei ist).

Eine solche Prüfung darf nie nur auf der Dateiendung basieren, die ist auch für Laien beliebig veränderbar. Eine Überprüfung des ContentType ist da schon eine wesentlich größere Hürde für Otto Normalsurfer, für die Absicherung gegen irrtümlich falsche Datei-Uploads sollte das ausreichen. Wer genug kriminelle Energie hat, wird sich davon aber nicht abhalten lassen und seinen Browser überreden einen falschen ContentType mitzuteilen. Für Interessierte gibt es dazu eine nette Präsentation: http://www.scribd.com/doc/2971490/Secure-PHP-Upload

Teil 2: Mehrere Alben verwalten

Mein Ansatz dazu war, jedem neu angelegten Album als ID den aktuellen Timestamp zu verpassen. Jedes Album wird in ein File persistiert, dass als Namen die ID trägt, und in einem data Verzeichnis gesammelt wird. Zur Erstellung der Liste, welche Alben vorhanden sind, wird dann einfach mit der entsprechenden PHP-Funktionen (glob) durch das Verzeichnis gewandert.

Sonntag, 2. November 2008

A2: PHP

Beim Lesen der Vorschau ist mir sofort einiges eingefallen, um das Leben (und das Programmieren) zu erleichtern.

Da wären erstens folgende beiden Funktionen zum Lesen und Schreiben einer Datei, die das File-Handling (fopen, fclose) ersparen:

Für die einzelnen Tracks braucht man nicht für jedes Formularfeld eine eigene Variable, sondern kann Arrays verwenden:

<input name="titel[0]" value="" type="text"> <input name="length[0]" value="" type="text">
...
<input name="titel[9]" value="" type="text"> <input name="length[9]" value="" type="text">

Im PHP kann dann ganz einfach über die Array-Einträge iteriert werden:
for($i=0; $i<10; $i++)
{
if($titel[$i]!="")
$album->tracks[] = new Track( $titel[$i], $length[$i] );
}

P2: Anforderungen

Die Task-Analyse war für diese Aufgabe recht schnell erledigt. Ausgehend von unserer Beschreibung der Projektidee wurde überlegt, welche einzelnen Tätigkeiten hinter den groben Forderungen ans System stecken - die Benennung (Überschriften) der Tasks war dann quasi schon fertig, und damit auch die Taskliste. Die Beschreibung der Tasks konnte aus der Überlegung der einzelnen Arbeitsschritte sowie Vor- und Nachbedingungen erledigt werden. Die UseCases waren dann eigentlich nur mehr das Umsetzen der grafischen Darstellung.

Nichtfunktionale Anforderungen laufen immer schnell Gefahr, sehr schwammig zu werden. Es stehen zwar schnell die üblichen Verdächtigen wie "Usability", "Performance" und "Wartbarkeit" im Raum, doch sind diese nicht direkt messbar. Sehr hilfreich sind an dieser Stelle Kennzahlen: Requests/Sek., Responsetime/Request, Mean Time Between Failure (MTBF), Mean Time Between Maintenance (MTBM), Mean Time To Recover (MTTR). Für die Messung der Usability haben wir das Kriterium definiert "80% der Testprobanden sollen in der Lage sein, die Aktionen Gruppenanmeldung und Prüfungsanmeldung innerhalb von einer halben Minute erfolgreich durchzuführen.".

P1: Projektidee

Zufälligerweise habe ich mich kurz vor der ersten PR-Einheit mit A4J (Ajax für JSF; ein Bestandteil der RichFaces Bibliothek) beschäftigt, wo mir auch die Komponenten a4j:push und a4j:poll untergekommen sind. Schon damals habe ich mir gedacht, dass diese Funktionalität sinnvoll für eine Anzeige freier Plätze (bei Reservierungssystemen aller Art) ist.

Die Aufforderung eine eingene Projektidee zu erstellen, kam dann gerade recht. Eine wesentliche Motivation gerade für unser Thema (LVA-Verwaltung) war die eigene Erfahrung mit ebensolchen an verschiedensten Universitäten.

An der Uni Wien gibt/gab es Univis, wo ich alle Prüfungsergebnisse ansehen kann. Zusätzlich tragen einige, aber nicht alle LVA-Leiter, die Noten auch ins PISWI ein. LVA-Anmeldungen finden entweder über das PISWI statt, oder aber im Rahmen einer Vorbesprechung, in der man sich auf eine Liste eintragen muss (einige LVA-Leiter entscheiden übrigens erst dann über einen Fixplatz anhand von Kriterien wie Studienabschnitt oder Anzahl erfolgloser Teilnahmeversuche in Vorsemestern). Die meisten - und verbindlichsten - Informationen findet man dann wiederum auf der Homepage des jeweiligen Vortragenden, vor allem wenn die LVA geblockt ist (da ist PISWI vermutlich mit der Terminverwaltung überfordert).

An der TU Wien gibt es TUWIS++, das im wesentlichen alle Funktionalitäten vom Univis und dem PISWI vereint, und noch etliches mehr bietet (Terminkalender, LVA-Evaluierung, etc). Für die meisten LVAs findet man dort alles was man braucht: Inhaltsangaben, Termine (sowohl bei Dauer- als auch bei Blockterminen), Anmeldungen zu LVA und Prüfung, ... Aus der Reihe tanzen vor allem die "Mathematiker" (Mathematik 1/2, Statistik) - sie haben eigene Homepages wo vor allem die Übungstermine angekündigt werden sowie die jeweils vorzubereitenden Beispiele. Völlig verschieden gehandhabt wird hingegen auch hier die Verbreitung der Vortragsfolien: von per USB-Stick oder Mail (bei exklusiveren LVAs im Masterstudium mit nur ~10 Teilnehmern), Institus-Homepage, Blog, und TUWEL Elearning Plattform habe ich schon alles einmal erlebt.

An der MedUni Wien existiert das Problem trotz der geringen Anzahl an Studiengängen ebenfalls, auch wenn man es ohne Kratzen an der Oberfläche nicht immer gleich merkt. Sowohl Human- als auch Zahnmedizin sind extrem "verschult". Kurz vor Semesterbeginn meldet man sich zu einer Praktikums-Kleingruppe (ca. 10 Studenten) an, und kann dann anhand der Gruppennummer im Studenplan nachsehen, wann man zu welchem Praktikum in welchem Raum erscheint (angesichts der Tatsache dass es ca. 70 Gruppen im 1. Jahr gibt eine immer aufs neue spannende Suche). Vorlesungen finden prinzipiell von Montag bis Freitag von 8-12 Uhr statt, die Themen der einzelnen Einheiten kann man fürs Ganze Jahr im Voraus dem Stundenplan entnehmen - nicht aber die Vortragenden. Da es keine Hörsäle gibt die groß genug für ca. 700 Studierende im 1. Jahr sind, werden diese auf 3 Kohorten (= 3 Hörsäle) aufgeteilt. Ist man brav, sitzt man dann im eingeteilten Hörsaal. Böse Jungs und Mädchen möchten aber manchmal lieber dem unterhaltsamsten / einprägsamsten Vortragenden lauschen. Die notwendige Information sollte man eigentlich im Vorlesungsverzeichnis finden - das Problem ist nur: die Vortragenden sind fast nie dort wo sie laut Plan sein sollten (falls es nicht überhaupt andere Vortragende sind, weil die Realität der Verfügbarkeit zB bei klinisch tätigen Professoren nicht immer der Jahresvorausplanung entspricht). Für die Pflichtlehrveranstaltungen ist das aber in der Praxis eher verschmerzbar. Jeder Medizinstudent muss aber auch noch Wahlfächer absolvieren, und hier gibt es keinen rettenden Stundenplan. Ankündigungen können im Vorlesungsverzeichnis, auf einer Institutshomepage, oder auch quasi "unter Ausschluss der modernen Öffentlichkeit" in "versteckten" Schaukästen irgendeines finsteren AKH-Gangs zu finden sein. Die Anmeldung erfolgt dann je nach Laune des Abhaltenden per Mail, persönlicher Anmeldung im Sekretariat, oder in der Vorbesprechung, die Termine richten sich oft kurzfristig nach Patientenandrang.