Der Partygraph, oder: Aaron hat wieder mal programmiert

Vor zwei, drei Wochen spazierte ich mit Jakob, einem Freund von der Uni, durch die Gegend und suderte darüber, daß ich doch so gerne mehr programmieren (lernen) würde, aber kein "Projekt" hätte, daß mich motivieren würde. Klar könnte ich irgendwie stur irgendwelche Programmierübungen runtercoden, aber das ist unglaublich zaaaaaaach. Als Faules Aas™ brauche ich etwas, das mich motiviert. (Oder was "wichtigeres" aber zacheres, das ich prokrastinieren kann.)

Jakob schlug daraufhin vor, ich solle doch ein Visual für seine Party machen, die zwei Wochen später stattfinden sollte. Nach etwas Rumgefuchtel, mit dem ich allgemeine Ahnungslosigkeit und spezielles Unwissen was Grafisches angeht signalisieren wollte, begann ich doch etwas rumzugrübeln.

Denn eine Idee hatte ich irgendwie doch schon: Den Partygraphen.

In meinem Freundeskreis werden oft und gerne mal Graphen gezeichnet. Beziehungsgraphen nämlich. Macht die Polyamorie doch oft sehr viel übersichtlicher, wenn man gleich auf einen Blick sehen kann, wer denn jetzt der Metamour von wem ist usw. Und auf Parties wird gern mal ein ganzes Whiteboard vollgezeichnet. (Mein Freundeskreis ist, teilweise, etwas ... eng verknüpft.)

Ven Diagramm

Auch finde ich es gerade auf Parties immer sehr spannend zu erfahren aus welche "Ecke" der Party diese und jene Person denn kommt, sprich: Wen kennt diese Person denn, daß sie sich hier, heute auf dieser Party wiederfindet?

Der Gedanke ein Tool zu basteln, das diese oft unsichtbaren Verbindungen sammelt, sichtbar macht und interessant visualisiert hat mich schon länger fasziniert. Mit der Party hatte ich einen konkreten Anlaß und, noch wichtiger, eine Deadline! Und durchh ein bißchen brainstorming mit Jakob bekam ich den Eindruck auch jemand wie ich, mit meinen begrenzten Programmierkenntnissen, könnte sowas hinbekommen.

Die Funktionalität des Tools sollte wie folgt sein: Über einen irgendwo auf der Party rumstehenden Computer solltens ich Leute via eines selbstgewählten Nicks in den Partygraphen eintragen können. Weiters werden die bereits im Graph eingetragenen Nicks angezeigt und der User kann anhackerln, welche davon er bereits kennt. Die gesammelten Information werden dann zu einem Graphen zusammengetragen umd abgespeichert. Währenddessen generiert ein zweiter Prozess aus diesem Graphen eine hübsche Visualisierung, die mittels Beamer auf eine Wand geworfen wird. Simpel, hübsch und hoffentlich nicht ganz uninteressant.

Ich machte ich also ans Werk. Zuerstmal Grundlegendes: Ich entschied mich, das ganze in Python zu coden. Der Hintergrund des Projekt erschien mir passend hack-y, und ich wollte es mir sowieso mal genauer anschauen. Und Python hat ja auch eine library für quasi alles, da find ich sicher was.

It's full of frameworks!

Schnell stellte sich heraus: Mein Gedanke war korrekt. Es gibt tatsächlich Python Tools um alles mögliche mit Graphen zu machen. Und zwar gefühlte drölfzig. Die alle BEINAHE dasselbe machen, nur halt irgendwie ein bißchen anders. m(

Nach etwas herumrudern und gelegentlichem Gefluche entschied ich mich für Pygraphviz für das Graphenbasteln, Knoten- und Kantenfrickeln usw. Mit viel Trial und Error hatte ich dann bald was, das mir aus einer Eingabe einen Knoten bastelte, überprüfte ob der der schon im Graph vorhanden war, Kanten zu einer Liste von anderen Knoten erstellte und mir das ganze dann auch noch in einer netten DOT Datei zwischenspeicherte.

(Für die DOT Datei, die dabei entsteht, sind mir dann auch noch lustige Dinge eingefallen, die man in kommenden Versionen implementieren könnte.)

Für die Visualisierung wollte ich etwas haben, daß dynamisch auf neu eintreffende Informationen reagierte. Es sollte also kein Film erstellt werden, der dann einfach abgespielt würde, sondern der Graph sollte ständig neu gerendert werden. Eventuell ein bißchen interaktiv, oder zumindest optional interaktiv, aber auch mit der Fähigkeit einfach über das Script direkt abgesprochen zu werden, ohne daß irgend ein Mensch daneben stehen musste um es zu bedienen.

Zuerst wollte ich, zur besseren Übersichtlichkeit, eine zweidimensionale Visualisierung haben, doch schnell stellte sich heraus, das die ganzen 2D Tools entweder nicht dynamisch waren (Beispielsweise via. Graphviz die Entstehung des Graphen rendern und dann als Film abspielen) oder aber zuviel Interaktion benötigten. (So gibt es einen Haufen netter Graphen-/Netzwerk-Visualisierungstools, die aber alle mehr dafür gedacht sind die Daten einem Nutzer zur interaktiven Untersuchung aufzuarbeiten als ein nettes Visual zu generieren, daß man auch alleine lassen könnte.)

Was selber coden überstieg sowohl meine Fähigkeiten als auch meinen Zeitrahmen, ich wollte etwas das mir das nitty-gritty des Renderings (Wo platziere ich den Knoten, wie schau ich das die nicht kollidieren, was für ein Layout, ...) möglichst abnimmt und dem ich einfach die DOT Datei füttern konnte und fertig.

So etwas in der Art fand ich dann, halt in 3D, in Ubigraph. Die Visualisierung übernimmt ein Server, der dann via RPC von diversesten Sprachen aus angesprochen werden kann. Das die genaue Platzierung, Layout und so weiter übernimmt der Server selber, einzig Knoten, Kanten und ein paar Attribute (Farbe, Form, Größe, Beschriftung, etc.) muss das eigene Script übergeben. Das ganze wirkte recht performant und die entstehenden Graphen sahen auch nicht unhübsch aus. Yay!

vis

(Beim ersten Rumrickeln merkte ich schnell, daß das arbeiten mit Ubigraph Knotenobjekten eher zäh ist, wenn es darum geht beispielsweise neue Kanten von einem neu hinzugekommen Knoten zu einem bestehenden Knoten zu erstellen. Nach etwas rumgeschimpfe ist mir dann aber eingefallen, daß Python ja Dictionaries hat, und ich verwendete eines, um die Knoten aus meiner DOT File etwas handlicher auf Ubigraphs Knotenobjekte zu mappen. Yay, Dictionaries!)

Ich hatte also etwas, um aus Daten Graphen zu basteln und etwas, um diese Graphen dann zu visualisieren. Fehlte noch das Frontend. Und das war vermutlich die größte Hürde, denn da hatte ich noch sehr wenig gemacht. Ich stellte mir irgendwas simples, webbasiertes vor, brauchte es doch nur ein Textfelt für den Nick und dann eine Möglichkeit anzukreuzen, welche der bestehenden Nicks diese Person bereits kennt. Doch mit Web-Zeugs kannte ich mich ungefähr so gut aus wie Python: Praktisch garnicht. Auch musste mein Webfrontend ja irgendwie mit meinem Pythonscript im Hintergrund reden. :P

Etwas ratlos googlte ich vor mich hin, stieß auf CGI-Skripte und schauderte bei dem Gedanken da jetzt auch noch einen Webserver aufzusetzen, nur für das kleine Frontend. Doch zum Glück stieß ich dann auf Web.py, ein ganz nettes Framework für WebDev via Python. Mit etwas rumprobieren und viel googlen schaffte ich es dann auch eine völlig unverzierte, hässliche Webseite auszuliefern und aus dem Input der beim Abspeichern zurückkam den gewählten Nick, wie auch die damit zu verbindenden Knoten rauszusaugen.

front

Ich hatte also einen quasi fertigen Prototypen, und das geradezu überpünktlich. (Sprich: Das ganze lief eine halbe Stunde vor der Party. Ok, die Anleitung und Beschreibung oben hab ich dann noch auf der Party geschrieben. Und ein paar Bugs wurden auch noch gefixt. Und...)

Deployment

Das ganze wurde, in Ermangelung eines besseren Platzes, in der hinstersten Ecke von Jakobs Küche aufgestellt und der Beamer so montiert, daß er auf die Decke strahlte. Wo er nur zu sehen war, wenn man in der Küche stand. Und dann eigentlich auch nur richtig, wenn man direkt drunter stand. -_-

Egal, das Ding lief, es wurde aufgestellt und ich war neugierig was passierte. Schon beim Aufbau gab es erstes Interesse: Ein, zwei Leute die ebenfalls in der Küche standen fragten uns, was das denn würde. Zu diesem Zeitpunkt waren die ersten Knoten (Ich, Jakob, Ines, Boki) schon hinzugefügt, es gab also schon etwas zu sehen, aber ich wollte nicht zuviel Hilfestellung geben, sondern forderte die Leute einfach mal auf zu meinem Laptop zu gehen, sich die Beschreibung durchzulesen und damit rumzuspielen.

Zu meiner Überraschung begriffen nicht nur alle sehr schnell, was zu tun sei und wie das ganze funktionierte, der Partygraph stieß auch auf reges Interesse. Nach den ersten beiden Leuten, den ich noch etwas Hilfestellung gab, lehnte ich mich zurück und beobachtete nur immer am Rande, ob eh alles funktionierte. (Meistens tat es das auch. Nur der Screensaver funzte hie und da rein.)

Schnell traten Netzwerkeffekte auf: Leute, die den Partygraph lustig fanden suchten sich ihre Bekannten und animierten sie dazu, sich ebenso einzutragen. So wuchs der Graph in kurzer Zeit an. Am Ende der Party hatten sich 24 Leute eingetragen, was mit den geschätzten 50-60 Leuten ein Schnitt ist, der mich sehr positiv überrascht hat. Auch waren praktisch alle Rückmeldungen positiv, Interesse war hoch und auch der Effekt als "Social Object" war hoch, denn Leute redeten über das Tool bzw. animierten einander dazu es zu benutzen.

Fazit

Ich empfinde das Projekt "Partygraph" als vollen Erfolg:

  1. Ich hab mehr Python gelernt!
  2. Ich hab eine lustige Sache gebastelt!
  3. Ich strotze vor Ideen, was man noch implementieren könnte!
  4. Leute fanden die Sache cool und manche, wie Jakob zB., wollen daran weitercoden.

Doch es gibt noch einiges zu tun:

  • Der Code ist ... nicht schön. Häßlich. Geradezu widerlich sogar.
  • Das Teil braucht WIRKLICH einen besseren Namen.
  • Das Frontend muss viel hübscher und angenehmer zu bedienen werden.
  • Die Visualisierung könnte man noch VIEL hübscher machen.
  • Hab ich erwähnt wie furchtbar der Code ist?

Trotzdem. Ich bin happy und gespannt wo das noch hingeht. :)