Im letzten Post habe ich über die Vorteile berichtet, die meine Implementierung einer REST Schnittstelle für die Erzeugung fachlich - zumindest halbwegs - sinnvoller Testdaten bedeutet hat. Nun, einige Tage und damit eine strukturelle Änderung des Systems später, hat sich das geschilderte Vorgehen einmal mehr bewährt.
Anstatt die Testdaten einer Migration zu unterziehen wurden die Testdaten nach einer Erweiterung des Anwendungssystems einfach ein zweites Mal über das REST API eingespielt. Mit den nun geänderten und erweiterten Verarbeitungsvorschriften wurden nun Daten erzeugt, die in der vorangehenden Anwendungsversion noch nicht verfügbar waren.
Auf Basis dieser Daten soll nun ein Reporting mit einigen grafischen Diagrammen erstellt werden. Eine Aufgabe in der zur gleichen Zeit ein möglichst optimiert ablaufenden Datenanalyse und zusätzlich eine Visualisierung entwickelt werden muss.
Zwei an sich gänzlich unterschiedliche Aufgaben zur gleichen Zeit umzusetzen ist für mich nicht so einfach. Offensichtlich bin ich nicht fähig, effizient Multi-Tasking auszuführen. Daher habe ich einen Weg gesucht, diese Aufgabe in kleine, beherrschbare Teile aufzubrechen.
Einzelaufgaben
Ich habe die gestellte Aufgabe dazu in folgende Teile aufgebrochen:
- Definition einer Datenstruktur: anhand der Anforderungen habe ich bestimmt, welche grundlegenden Daten ermittelt werden müssen. Für diese habe ich eine ganz einfach Repräsentation definierte, die als Schnittstelle zwischen berechnendem Backend und der grafischen Ausgabe dient.
- Erweiterung der REST Schnittstelle: die im ersten Schritt definierte Datenstruktur wurde über die bereits bestehende Schnittstelleninfrastruktur exportiert. Im Wesentlichen musste nur ein Aufruf der Berechnungsfunktionen gekapselt werden. Die einfache Containerklasse für den Transport der Ergebnisse musste hier nicht zusätzliche bearbeitet werden.
- Implementiertung erster Berechnungsfunktionen: die Verarbeitung der Daten ist im vorliegenden Fall algorithmisch nicht trivial. Die vorliegenden Daten müssen anhand unterschiedlicher Perioden abgegrenzt und anhand variierender Regeln bewertet werden. Hier kann die zentrale Berechnungslogik mit anpassungsfähigen “Mixins” den jeweiligen Anforderungen angepasst werden.
- Realisierung der grafischen Darstellungen: selbst wenn die numerischen Ergebnisse der Analyse in vielen Fällen ähnlich oder sogar identisch sind, müssen je nach Zielsetzung dennoch unterschiedliche Visualisierungen entwickelt werden.
Bei diesem Vorgehen ergibt sich jedoch eines der typischen “Henne / Ei Probleme!”
Während der Entwicklung der Algorithmen sollte die Visualisierung verfügbar sein, um die Ergebnisse bewerten zu können. Die Entwicklung der Visualisierung hingegen erfordert verlässliche Informationen, um die Gestaltungsmöglichkeiten für Aussagefähigkeit und Benutzbarkeit während der Entwicklung prüfen zu können.
Visualisierung mit Mathematica
Das Software System Mathematica verwende ich seit 1991. Damals habe ich die Version 2.1 auf einer NeXTstation eingesetzt. Mit Mathematica 6 bin ich dann auf Windows gewechselt (und habe diese Implementierung gehasst). Nun verwende ich Mathematica 8 & 9 auf Mac OSX und bin wieder zufrieden mit dem bereitgestellten Notebook Client.
Mathematica verfügt über einige praktische Funktionen zur Manipulation und Visualisierung von Datenstrukturen. So liegt es eigentlich nahe, diese Lösung auch in der Entwicklungsphase einzusetzen um die Ergebnisse der Algorithmen zu bewerten und die ersten Visualisierungen zu gestalten.
Über die REST Schnittstelle können die Ergebnisse der Analysen aus der Anwendung abgerufen werden. Stark vereinfacht erhält man so ein JSON Dokument mit einer Vielzahl unterschiedlicher Datenpunkte:
[ { "date": 1261998000000, "week": 53, "year": 2009, "count": 3, "value": 16530.00 },
{ "date": 1262600280000, "week": 1, "year": 2010, "count": 4, "value": 18730.12 },
...
]
Je nach Auswertung, werden unterschiedliche value
Elemente der Struktur hinzugefügt. Allen gemein ist aber die zeitliche Bestimmung eines Datenpunkts. Das System verwendet intern für einige Prozesse als kleinste Einheit die Kalenderwoche. Diese ist daher gesondert in den Datenpunkten ausgezeichnet, so dass sie in den Visualisierungen nicht neu berechnet werden muss. Zusätzlich wird aber immer der in der UNIX / Java Welt gebräuchliche Zeitwert mitgeliefert (Milisekunden seit dem 1.1.1970 UTC).
In Mathematica 9 kann auf diese Schnittstelle durch den Import
Befehl zugegriffen werden. Dazu wird einfach der URL übergeben und zusätzlich signalisiert, dass man ein JSON Dokument zu empfangen erwartet.
import = Import["http://localhost:8080/controlling/rest/projects/evaluation/2010",
"JSON"]
Das Ergebnis ist eine Mathematica Datenstruktur - eigentlich eine Liste aus Optionswerten. Sollen aus dieser Liste einzelne Werte in einer nachfolgenden Berechnung genutzt werden, können diese einfach in die mathematischen Ausdrücke eingesetzt werden:
values = Map[Function[x, "value" /. x], import]
In diesem Fall werden die value
Werte aus dem Ergebnis selektiert und zu einer neuen Liste zusammengefasst. Diese Werteliste kann nun einer Visualisierungsfunktion übergeben werden. Da ich derzeit noch mit der Implementierung und Optimierung der Analysefunktionen beschäftigt werden, nutze ich hier noch die einfachste Darstellung als BarChart
:
BarChart[ values, ChartStyle -> "Pastel"]
In meinem Notebook habe ich die Zwischenergebnisse nicht genutzt und zudem auch die Ergebnisse von zwei Jahren zusammengefasst. Daher ist das verwendete Programm ein wenig kompakter gestaltet:
BarChart[ Map[Function[x, "value" /. x],
Join[Import["http://localhost:8080/controlling/rest/projects/evaluation/2010", "JSON"],
Import["http://localhost:8080/controlling/rest/projects/evaluation/2011", "JSON"]]],
ChartStyle -> "Pastel"]
Mit diesem Mathematica Ausdruck erhalte ich während der laufenden Entwicklung auf Knopfdruck eine aktuelle Visualisierung der Ergebnisse meiner Analysefunktionen. Das Ergebnis sieht sogar durchaus ansprechend aus.
Der Datenzugriff über die REST Schnittstelle ermöglicht eine schnelle und einfache Integration mit spezialisierten Hilfsmitteln. Auf diese Weise kann eine schnelle und einfache prototypische Umsetzung der Anforderungen zu einem frühen Zeitpunkt getestet werden. Rechenfehler der Analysefunktionen werden schnell offenbar und der praktische Nutzen einer Auswertung erweist sich recht früh. Ist der Nutzen einer Auswertung nicht erkennbar, können die vorliegenden Anforderungen schnell überarbeitet oder gestrichen werden. Die zur Verfügung stehende Entwicklungszeit kann damit zielgerichtet investiert werden.