NumeRe v1.1.7 Release Candidate ist verfügbar!
Spreadsheets bzw. Tabellenkalkulationen (Microsoft Excel & Co.) werden für alle möglichen Aufgaben eingesetzt. Dabei brillieren sie häufig durch ihre Einfachheit und Flexibilität. Verlässt man aber das Terrain der "Allerwelts-Kalkulationen", kommt man recht bald and den Punkt, ab dem solche Applikationen nicht mehr praktikabel sind. Wir wollen in diesem Artikel betrachten, in welchen Aspekten NumeRe dann plötzlich die Nase vorne hat und warum es sich lohnt, sich mit der "etwas anderen" Herangehensweise von NumeRe auseinanderzusetzen.
Ist das eine schamlose Eigenwerbung? Nur teilweise, denn die Argumente lassen sich auf jede Lösung übertragen, die sich in der Lücke zwischen "einfachen" Tabellenkalkulationen und "echten" Programmiersprachen bewegt.
Bevor wir in die Materie einsteigen, möchten wir insbesondere für alle, die NumeRe nicht kennen, einmal klar stellen, dass NumeRe kein direkter Ersatz für Tabellenkalkulationen ist und auch ein davon recht verschiedenes Bedienkonzept besitzt. Während in Tabellenkalkulationen der größte Teil der Logik selbst Teil der Tabelle ist (in Gestalt von Formeln, die Zellen zugewiesen werden), sind Logik und Daten in NumeRe getrennt: die Logik befindet sich in einem Script bzw. ein oder mehreren Prozeduren, die Daten werden in Tabellen verwaltet, die ihrerseits reine Datenstrukturen sind. Die Arbeit in NumeRe hat damit einen sehr viel deutlicheren Fokus auf eine strukturierte Programmierung.
Für einen erste Gegenüberstellung, wie man ein einfaches Problem in Excel und NumeRe löst, haben wir in der Vergangenheit schon einen Artikel veröffentlicht, den wir allen Neulingen ans Herz legen wollen.
Bei Tabellenkalkulationen erkennt man meist erst recht spät in der Entwicklung einer Lösung, wie dürftig ihr Toolsupport für komplexere Lösungen tatsächlich ist. Insbesondere wenn es um die Fehlersuche geht oder man die erstellte Lösung zu einem späteren Zeitpunkt nochmals modifizieren will, sind richtige Programmier-Tools Gold wert. Ohne sie können solche Situationen in echte Alpträume ausarten.
Natürlich kann man auch in Excel schrittweise Funktionen ausführen, um Fehler zu isolieren, allerdings ist der Support für eine richtige Zustandsüberwachung und zum Springen innerhalb des Call-Stacks mehr als begrenzt.
Ein richtiger Debugger erleichtert diese Aufgabe ungemein. In NumeRe kann man Breakpoints setzen, an denen der Debugger anhält und die aktuellen Werte der Variablen listet. Man kann diesen Breakpoints auch Bedingungen zuweisen, so dass sie nur auslösen, wenn ihre Bedingungen erfüllt sind.
Schonmal das Problem gehabt, dass nach mehreren Änderungen an der Logik plötzlich nichts mehr funktioniert? Und dann auch noch wegen fehlender Cloud-Verbindung keine älteren Versionen mehr verfügbar sind?
Das kann mit NumeRe nicht passieren. Jeder Speicherstand legt eine neue Version der Datei in der lokalen Versionsverwaltung an. Man kann die Änderungen zwischen zwei beliebigen Versionen direkt vergleichen (mittels eines "Unified Diffs") oder ältere Version wiederherstellen. Damit nicht genug: man kann auch Versionen zusätzlich annotieren (über "Tags"), so dass man sie in der Revisionsübersicht auch schnell wieder findet. Zum Beispiel könnte man nach einem abgeschlossenen Teil der Entwicklung eine solche Version mit einem entsprechenden Kommentar versehen.
Wir meinen hier natürlich nicht, dass man Kommentare in irgendwelche Zellen des Spreadsheets schreibt, die dann unter Umständen noch mit Daten verwechselt werden können, sondern echte Code-Kommentare, die Gedankengänge und Ideen an die zugehörigen Code-Block ergänzen können, so dass auch jemand anderes als der Urheber versteht, was man sich dabei gedacht hatte. Diese Kommentare können teilweise auch in eine PDF-Dokumentation umgewandelt werden.
Refactoring? Darunter versteht man das Überarbeiten vorhandener Lösungen, wenn die Code-Qualität nach der Entwicklung nicht mehr den Standards entspricht. Als Beispiel wären da sehr lange und unübersichtliche Code-Segmente zu nennen. NumeRe bietet die Möglichkeit, markierte Segmente in eigene Prozeduren zu extrahieren und den Code dadurch wieder übersichtlicher zu gestalten. Außerdem können Variablen mit einer einfachen Funktion sicher umbenannt werden, um ihren Zweck hervorzuheben.
Ein statischer Code-Analyzer kann Probleme und Optimierungen detektieren, ohne dass der Code dafür ausgeführt werden muss. Dabei gibt es natürlich keine Garantie, dass der Code fehlerfrei läuft, wenn keine Probleme gefunden werden. Allerdings kann er helfen, typische Probleme zu vermeiden.
Aufgrund der "Andersheit" der Funktionsweise von NumeRe ergeben sich Vorteile, welche sich insbesondere bei komplexeren Problemen offenbaren, bei einfachen Problemen aber dagegen fast schon mühselig werden können. Hervorzuheben ist hier die eingangs schon genannte Trennung von Daten und Logik, die deutlich mehr Programmierung erfordert als es Tabellenkalkulationen tun. Gleichzeit ermöglicht das aber auch deutlich mehr Freiheiten und eine verbesserte Kontrolle über den aktuellen Zustand der Software.
Eines der größten Probleme in fortgeschrittenen Spreadsheet-Lösungen ist, dass sowohl Daten als auch Programmlogik in derselben Entität (dem Spreadsheet) verwaltet wird. Das mag erstmal wie kein besonderes Problem erscheinen, doch damit wird verhindert, dass die Logik einfach portierbar wird, also auf andere Probleme angewendet werden kann.
In NumeRe werden Daten in sogenannten Tabellen verwaltet, die jedoch reine Datenspeicher sind. Es ist nicht möglich, Spalten, Zeilen oder einzelnen Zellen Formeln wie in Excel zuzuweisen, die bei Änderung von Werten automatisch ausgeführt werden. Jegliche Operation muss durch davon getrennten Code in einem Script oder eine Prozedur erfolgen.
Weil Daten und Logik in Spreadsheets so untrennbar verbunden sind, kann es schnell mal passieren, dass beim Modifizieren der Logik auch die Daten geändert werden, ohne dass man es merkt. Viel zu schnell wählt man die falsche Zelle aus und hat irgendetwas getippt.
Das kann in NumeRe nicht passieren. Code wird in anderen Dateien verwaltet als Daten und selbst wenn du geladene Dateien modifizierst, wird das nicht automatisch in den Quelldateien gespiegelt. Das musst du explizit durchführen.
In NumeRe werden Lösungen getrennt von den Daten entwickelt. Zwar wird man die Daten parallel betrachten, um mögliche Ansätze auszuwählen, jedoch wird man niemals direkt auf den Daten entwickeln. Tatsächlich werden die meisten Lösungen die folgenden drei Schritte umfassen:
Daten laden
Daten verarbeiten
Ergebnisse speichern
Dabei können die einzelnen Schritte ganz unterschiedlich komplex und umfangreich sein, wichtig ist aber, dass die Daten erst bei der Code-Ausführung ins Spiel kommen und nicht bereits während der Entwicklung. Dadurch erhält man automatisch Lösungen mit einer höheren Abstraktionsebene, die tendenziell für mehr unterschiedliche Anwendungsfälle einsetzbar sind.
Mit der höheren Abstraktionsebene kommt auch der Aspekt der Wiederverwendbarkeit bereits entwickelter Lösungen ins Spiel. Du wirst feststellen, dass deine Lösungen mit zunehmender Erfahrung abstrakter und wiederverwendbarer werden, so dass du alsbald eine ganze Bibliothek an Lösungen vorzuweisen hast, die auf deine Probleme zugeschnitten sind.
Was NumeRe insbesondere im Vergleich zu gewöhnlichen Tabellenkalkulationen auszeichnet, sind die erweiterten Algorithmen für beispielsweise Fouriertransformationen, Differentialgleichungen und Fitten. Besonders beim Fitten steht im Vordergrund, dass NumeRe nicht nur auf ein paar ausgewählte Modelle beschränkt ist, sondern (nahezu) beliebige Funktionen als Modelle zum Fitten erlaubt.
NumeRe bietet von Haus aus Algorithmen für Fourier- (fft, fft2d) und Wavelet-Transformationen (fwt), mit denen Daten schnell und unkompliziert in den Frequenz- oder k-Raum transformiert werden können. Diese Algorithmen zählen in der modernen Datenwissenschaft zu den Standards und werden für vielerlei Anwendungsfälle eingesetzt, um tiefere Einblicke in die zu untersuchenden Daten zu gewinnen.
Insbesondere die Fourier-Transformation hat auch Anwendungen in der Konvolution von Daten, da eine Konvolution im Frequenzraum einer Multiplikation entspricht, die um ein Vielfaches schneller ist.
Genervt von den sehr begrenzten Trendlinienoptionen in Excel? In NumeRe kannst du nahezu beliebige ein- oder zweidimensionale Funktionen mit (fitw) oder ohne weitere Gewichtungsfaktoren (fit) an deine Daten anpassen lassen. Die Funktionen können aus ganzen Ausdrücken zusammengesetzt sein: A*sin(B*x)*exp(-C*x)+sqrt(cos(D*x)) Dabei gibt es nur sehr wenige Ausnahmen an Funktionen (z.B. Zufallszahlen), die nicht Teil eines solchen Ausdrucks sein können. Angepasst werden die definierten Parameter (in diesem Beispiel A, ..., D) der Funktion.
NumeRe kann gewöhnliche Differentialgleichungen (Ordinary Differential Equations, ODE) numerisch integrieren. Dazu stehen neben dem Runge-Kutta-Verfahren noch weitere Varianten als mögliche Integratoren zur Verfügung. Die Differentialgleichungen müssen erster Ordnung sein, es besteht aber die Möglichkeit, Differentialgleichungen n-ter Ordnung in n Differentialgleichungen erster Ordnung zu überführen und diese als gemeinsames System anzugeben.
Neben einfachen Dialogboxen unterstützt NumeRe das Erstellen ganzer Applikationen, die in einem separaten Fenster laufen. NumeRe muss dabei weiter im Hintergrund laufen, es besteht aber die Möglichkeit, das NumeRe-Fenster komplett auszublenden, während die eigene Applikation läuft.
Etwas gewöhnungsbedürftig kann dabei der Layout-Algorithmus sein, der keine pixelgenaue Positionierung zulässt, sondern Elemente in automatisch skalierenden Gruppen organisiert. Der Vorteil besteht darin, dass es dann eine untergeordnete Rolle spielt, wie groß der Benutzer das Fenster machen möchte.
In den vorherigen Abschnitten haben wir hervorgehoben, dass sobald eine Implementierung eine etwas komplexere Logik jenseits einfachen Zahlen- und Zeichenkettenmanipulierens erfordert (die "magische Grenze"), sich mit NumeRe die deutlich wartbareren und besser zu kontrollierenden Lösungen erzeugen lassen. Insbesondere können die zugehörigen Implementierungen abstrakter gestaltet werden, womit die Wiederverwendbarkeit deutlich erhöht wird, was über die Zeit auch zu umfangreichen Bibliotheken führt.
Zugleich hat sich aber auch herausgestellt, dass eine Implementierung in NumeRe unterhalb der "magischen Grenze" eher aufwändiger als selbiges mit Tabellenkalkulationen ist. Wo diese "magische Grenze" genau ist, ist sicher von Mensch zu Mensch verschieden und wird daher jeder für sich herausfinden müssen. Sichere Indikatoren sind die folgenden:
Abhängigkeit von Makros
Verwendung mehrerer Tabellenblätter und deren gegenseitige Abhängigkeit
Bezeichnung des Spreadsheets als "Tool" ist ein häufiger Indikator
Logik innerhalb der Implementierung nur schwer nachvollziehbar und Formeln sind stark verschachtelt