Drücke „Enter”, um zum Inhalt zu springen.

Veröffentliche Beiträge in “Programmierung”

Ich entdecke und fixe Bugs, schreibe wilde Hacks… sprich: ich programmiere

Alten Daten einen Sinn geben

Jan 0

Mit meiner letzten Version habe ich es ermöglicht, dass ich die Charts nicht nur eines Jahres anzeigen kann. Dabei fiel mir auf, dass ich seit 2004 meine Charts bei Jahreswechsel auf die Platte gedumpt habe. Dort standen dann mit Komma getrennt, Interpret, Titel und die Anzahl, wie oft die Platte gespielt wurde, drin. Und da wurde mir klar, dass man beides gut miteinander kombinieren kann.

Also begann der lange, steinige Weg zur Version 4.4. Erstmal habe ich mein Projekt, dass bei BitBucket gehostet wird, auf den Git Flow umgestellt. Vorher war das eher Kraut und Rüben. Da ich ganz allein an dem Projekt arbeite ist, stellt mir meine Quellcode-Verwaltung das Branching Model als Linie dar, da nie Änderungen auf mehreren Zweigen erfolgen.

Ich begann ganz zaghaft mit einer Oberfläche, dann habe ich das Einlesen und Zerlegen der alten Charts-Dateien in Angriff genommen und diese dann über die Datenbankschnittstelle finden lassen. Dabei entstehen zwei Töpfchen: gefunden und nicht gefunden. "Nicht gefunden" kann heißen, dass ich die Bezeichnung geändert / verbessert habe oder die Platte verkauft wurde. Also gab es zwei Optionen: "Verwerfen" - das ging schnell und "Zuordnen" - das hat den Großteil der Zeit gekostet.

Für das Zuordnen musste ich erstmal jede Menge Komponenten, die ich schon für die "normale" Plattenverwaltung gebraucht habe und eine gemeinsam genutzte Komponente umziehen, Aufrufe korrigieren und dann konnte das Zuordnen beginnen. Nächste Hürde: Bisher hatte ich nie das permanente Wechseln zwischen zwei Screen (Übersicht und Suchmaske) in meinem Prozess. Die Datenbank rebellierte etwas, weil die Verbindung bereits geöffnet war oder der Garbage Collector sie mittendrin mal wegräumte.

Heute kam dann der letzte und entscheidende Schritt: Ich hatte alles soweit fertig, las die Datei ein, ordnete zu und lies mir nochmal die eingelesene Zeile und das zugeordnete Datenbankobjekt rausdumpen. Und irgendwie passte bei den manuell zugeordneten Sätzen zu Zuordnung nicht hin. Ursache war schnell gefunden: Die Charts basieren auf den einzelnen physischen Tonträger, die Suche für die Zuordnung aber auf den Veröffentlichungen. Klingt jetzt komisch, oder? Beispiel: Doppel-CD - die besteht aus zwei CDs, ist aber eine Veröffentlichung. Beides habe ich jetzt verwechselt. Jetzt musste ich nur schnell das komplette Programm mal kurz umbauen, damit sie Suche mit beiden Kriterien arbeiten kann und schon funktionierte alles.

chartseinlesen

Nachgebessert

Jan 0

Ich hatte jetzt die letzte Version der Plattenverwaltung mehrere Monate im produktiven Test und bin sehr zufrieden. Das Programm kann alles, was ich brauche, die Daten sehen aus, wie ich das erwarte. Im letzten Beitrag zur Plattenverwaltung hatte ich erwähnt, dass ich noch einige Punkte zum Thema Datenqualität und Statistik einbauen wollte, aber das habe ich lieber als Korrekturen direkt auf der Datenbank gemacht. Wenn ich so einen Blick auf die Daten werfe, sehe ich noch am ehesten, ob sich noch ein Fehler eingeschlichen hat.

Als das neue Jahr begann offenbarte sich eine kleine Unschärfe, an der eine Reihe von Änderungen hin. Als ich das erste Mal die Jahrescharts öffnete, sah ich nur, was ich dieses Jahr als abgespielt markiert habe. Die Vorgängerjahre, die ich im Datenmodell mit vorgesehen habe, konnten nicht angezeigt werden. Also bohrte ich ein Loch von der Oberfläche bis zur Datenbank durch, dass ich die speziellen Datensätze für die Jahrescharts auslesen kann. Und jetzt kann ich bei den Jahrescharts ein bestimmtes Jahr angeben und sehe sofort die passenden Daten.

Jahrescharts

An der Oberfläche nichts Neues

Jan 0

Ich habe mir mit der nächsten Ausbaustufe doch ziemlich viel Zeit gelassen. Und dabei gab es nach außen hin relativ wenig zu tun. Zur Erinnerung: Ich wollte in meine Plattenverwaltung als nächstes das Bearbeiten bereits existierender Tonträger integrieren. Dazu musste ich einen Tonträger auswählen - habe ich schon für das Abspielen. Und dann brauchte ich die Maske, wo ich alle Daten zum Tonträger sehe - habe ich auch schon für das Anlegen. Wo sollte dann also das Problem sein?

Zum einen musste ich beide miteinander verknüpfen. Natürlich möglichst so, dass keiner den anderen kennt. Wie soll das gehen, wenn auch noch Daten ausgetauscht werden? Ich erfand eine Klasse, mit der ich Workflows abbilden kann. Die funktioniert nach dem einfachen Prinzip des Stacks, d.h. am Anfang werden alle nötigen Bearbeitungsschritte (in Form der Viewmodels) reingestopft und wenn ein Schritt fertig ist, dann schickt er eine Nachricht - je nachdem ob abgebrochen oder weitergearbeitet wird. Meine Workflow-Klasse hat sich für die Nachrichten registriert und dementsprechend wird die Bearbeitung des Stacks fortgesetzt oder abgebrochen. Den Nachrichtenmechanismus habe ich in dem Atemzug auch gleich mit eingebaut. Damit war es für mich sauberer Dateidialoge unabhängig vom Viewmodel zu öffnen. Das war jetzt auch nicht der unheimliche Aufwand.

Der ganze Aufwand wartete in der untersten Etage - da wo das Mapping zwischen den Datenobjekten und der Datenbank statt findet. Ich hatte bis jetzt eine Klasse die den ganzen Zugriff abgebildet hat. Mit über 600 Zeilen Code war die schon ziemlich unübersichtlich geworden. Also zerpflückte ich die Klasse nach den einzelnen Anforderungen: eine Klasse für das Abspielen, eine für die Charts, eine zum Anlegen von Tonträgern. Jetzt zerfiel das Ganze und es machte auch wieder mehr Spaß neue Funktionalität einzubauen. Da ich die gleichen Objekte zum Anlegen wie auch zum Editieren benutze, musste ich erstmal die Datenobjekte umbenennen und merzte in dem Zusammenhang auch noch eine Architekturschwäche aus: Alle Assemblys hatten eine Abhängigkeit in die Datenbankschicht, da dort die Datenobjekte definiert waren. Also lagerte ich diese gleich in ein neues Projekt aus. Kurz und gut - ich baute einmal das komplette Untergeschoss um.

Der neue Modus funktioniert fast gleich von Anfang an, weil ich viel vom Anlegen wiederverwenden konnte. Jetzt muss ich nur noch ein paar kleine kosmetische Korrekturen machen, dann kann ich mir Gedanken machen, was ich mir als nächstes vornehme. Am liebsten hätte ich eine Ansicht, die mir ein paar Statistiken u.a. zur Datenqualität liefert. Ich habe festgestellt, dass etliche Cover nicht übernommen wurden bzw. was sonst noch an Daten fehlt. Das wird dann wohl der nächste Schritt sein...

Nächster Schritt

Jan 0

Meine Plattenverwaltung nimmt langsam Gestalt an. Nachdem ich die Basisfunktionen, die ich benötige (Anlegen, Abspielen und Alltime-Charts), fertig hatte, probierte ich ein bisschen herum und schaute, wie die Daten in der Datenbank landeten. Alles sah gut aus, deswegen konnte ich mich an die Version 4.1 wagen. Neue Features:

  • Jahrescharts
  • Anlegen soweit erweitern, dass man Veröffentlichungen mit mehreren Tonträgern (z.B. Doppel-CDs) erfassen kann

Die Jahrescharts waren wirklich simpel - ich musste die Alltime-Charts nehmen, andere Daten abfragen und fertig. Etwas kniffliger war da das Anlegen. Nicht die Datenstruktur - die ist ja simpel, schließlich hatte ich sie ja im Datenbankmodell schon so vorgesehen. Aber wie stelle ich sowas dar? In der alten Version wurde die Anzahl abgefragt und wehe, man hatte sich geirrt. Das sollte jetzt viel einfacher werden. Ich dachte schon an Tab-Reiter, verwarf den Gedanken aber wieder, weil auftauchende und verschwindende Tab-Reiter finde ich im Browser normal, aber sonst eher verwirrend. Ich entschloss mich einen Master-Detail-View zu nutzen, d.h. man hat eine Liste zu der man Elemente hinzufügen / entfernen kann und wenn man ein Element der Liste auswählt, erhält man die Detailinformationen, in dem Fall die Titel. Und wenn wir schon mal bei Detailinformationen sind - die musste ich auch aufspalten. Als Beispiel möchte ich z.B. die Blumfeld-Sammlung nennen - eine Box, die den Titel "Ein Lied mehr..." trägt, aber die ersten vier Alben der Band enthält (Ich-Maschine usw.). Jedes hat sein eigenes Cover und seinen eigenen Titel, aber alle teilen sie die gemeinsame Bezeichnung. Auch das hatte mein Datenbankmodell schon vorgesehen, jetzt musste nur noch eine Darstellung und die Umsetzung her. Ich habe eine kleine Schwäche für Expander, man kann da so schön unwichtige Informationen ausblenden. Also landeten die Liste mit den Tonträgern und die Detailinformationen (die zu 95% sowieso den Hauptinformationen entsprechen) in eingeklappten Expandern. Mir gefällt es so und es funktioniert auch richtig super. Beigefügt mal ein paar Bilder, sonst versteht man das Geschriebene doch eher schlecht.

[gallery ids="6086,6087,6088"]

Long time no see

Jan 0

Ich habe gerade mal geschaut... es war im Mai, wo ich den letzten Beitrag zum Thema Plattenverwaltung 4.0 geschrieben hatte. Es folgte eine lange Phase der Orientierungslosigkeit - wie sollte jetzt meine Oberfläche aussehen? Ich hatte vor Jahren auf Arbeit ein kleines Programm geschrieben, dass einige überschaubare Funktionen erfüllen sollte, die über Tab-Reiter auswählbar waren. So ähnlich stellte ich mir meine neue Oberfläche vor und fing an. Zuerst fing ich mit den Basics an: Die Tab-Reiter einzeln anwählbar machen und dementsprechend den Content auf der Hauptoberfläche (der nur simuliert war) umschalten. Dann spielte ich noch etwas mit Farben herum und gelangte dann zu einem ersten Entwurf, der mir zusagte.

pv_step01

Als ich anfing die einzelnen Aspekte der Oberfläche (Home, Anlegen, Abspielen) mit Leben zu füllen, kollidierte ich immer wieder mit meinen Farbeinstellungen. Also flog alles was farbig war, raus und schon arbeitete ich mit einer ziemlich nackt aussehenden Windowsoberfläche weiter. Als erstes ging es mit dem Abspielen los, da diese Funktionalität die einfachste war. Ich hatte schon mal mit einem Such-Control herum-experimentiert und band es ein. Bei meiner alten Plattenverwaltung hat es mich immer wahnsinnig genervt, dass ich ewig herumscrollen musste, um eine Platte zu finden. Es versprach alles einfacher zu werden. Die ersten Testläufe gegen meine simulierte Datenbank funktionierten perfekt. Also konnte ich mich dem nächsten Punkt zuwenden...

pv40_1Das Anlegen war der nächste Punkt, den ich auf dem Plan hatte. Ich klebte erstmal alle Controls auf die Oberfläche, ordnete sie ein bisschen, sorgte für ein anständiges Databinding (Für Laien: Die Daten und die Oberfläche miteinander verknüpfen) und dann gingen die ersten Tests los. Hier klappte was mit der Aktualisierung nicht, da kollidierte der Datentyp mit der Darstellung. Kleine Problemchen, die ich alle mit einer Suchanfrage lösen konnte. Hin und wieder schon ich die Controls zurecht, bis ich so halbwegs zufrieden war. Es konnte der letzte und entscheidende Schritt folgen: Ersetzen der Dummy-Daten durch den richtigen Datenbankzugriff. Hier tat ich mich anfänglich schwer, aber als ich einmal den Rhythmus raus hatte, war auch die Datenbank zügig angebunden.

Nachdem ich begann die einzelnen Programmpunkte mal testhalber anzuwählen, wurden mir klar, dass mich das Design kolossal nervte. Das mit den Tab-Reitern war zu umständlich und verbrauchte ständig Platz. Lieber eine einfach Startoberfläche und dann von dort aus die einzelnen Programmpunkte anwählen. Gesagt, getan... Das Schicke daran war, dass ich mich nur um das Startmenü kümmern musste, alle anderen Programmteile schalteten schon von allein auf den vorherigen Punkt zurück.

pv40_3Der Test konnte weiter gehen - einzelne Platten als abgespielt markieren. Die Datenbankanbindung arbeitete fast perfekt - einmal wurden alle Platten geladen und dann wurde entsprechend dem Filter immer nur ein- und ausgeblendet. Markierte Platten wurden in eine extra Liste geschoben, die zum Schluss gespeichert wurde. Nur der Filter brachte mich zur Verzweiflung. Einmal gefiltert, wurde die Liste nie neu sortiert, sondern die vorher ausgeblendeten Platten wurde einfach wieder unten an die Liste angehängt. Also - neu sortieren nach jedem Filtern. Hatte ich mich im Filter vertippt und die Liste war dadurch leer, konnte ich den Suchbegriff entfernen oder was anderes Suchen - die Liste blieb leer. Mh, ein Aktualisierungsproblem, auch gelöst. Jetzt endlich konnte ich den Punkt ordentlich ausprobieren. Dumm war nur, dass mir die Fehler erst auffielen, als ich die Daten schon in die Datenbank geschrieben hatte. Äußerte sich dadurch, dass auch nicht gespielte Platten in der Liste befanden. Nachdem vermeintlich alles erledigt war, markierte ich, verließ dem Programmpunkt, wählte ich in wieder an, markierte weiter und hoppla... da waren noch die alten Elemente in der Liste. Bloß gut, dass ich das rechtzeitig gemerkt habe.

pv40_2Anlegen entpuppte sich größtenteils als Fleißarbeit. Natürlich mussten jede Menge Daten geschrieben und gelesen werden, aber das ging sehr zügig von der Hand. Meine größte Sorge war ob das Framework die Verknüpfungen zwischen den Objekten gut hingekommt. Aber auch das lief sauber durch. Einzig die Persistierung (das dauerhafte Speichen der Daten) stellte sich quer, denn ich habe eine Verknüpfung zwischen der Platte und dem Interpreten bzw. dem einzelnen Titel und dem Interpreten. Das bescherte mir bei einer Single mit 2 Titeln drei mal den gleichen Interpreten als neue Datensätze. Als ich damit fertig war, konnte ich in den Praxistest gehen. Seither läuft das Programm in der Betaphase, d.h. ich starte es in der Entwicklungsumgebung und schaue immer mal auf die Daten, die so hin- und herhuschen.

Tabellen füllen

Jan 0

Viel Zeit habe ich nicht gebraucht, um das Programm zu schreiben. Es war ja nur eine einfache Konsolenanwendung, welche die Daten aus einer Textdatei gelesen hat, die Zeilen zerlegt hat und dann die automatisch erzeugten Objekte gefüllt hat, die abschließend in der SQL-Datenbank abgelegt wurden. Was mich wirklich Zeit gekostet hat, war die Datenqualität. Da ich bisher für meine Daten nur einfache Textfelder hatte, hatte ich stellenweise bis zu drei Bezeichnung für Label, z.B. "WARP", "Warp" oder "Warp Records". Das gilt natürlich auch für die Länder. Also habe ich immer wieder die Textdatei durchsucht, einheitliche Bezeichnungen gewählt und dann die Daten erneut eingelesen.

Wo es dann wirklich haarig wurde, war die Beschreibung, bei denen ich in letzter Zeit hinterlegt habe, wann und wo ich die Platten gekauft habe. Das hat insofern Spaß gemacht, weil da auch Texte wie "Zu Weihnachten geschenkt bekommen" drin standen. Also habe ich Weihnachten in den 24.12. umgewandelt, mich erinnert, wer mich das Geschenk gemacht hat... kurz und gut, ich habe versucht das Beste daraus zu machen. Mit der Belohnung, dass ich jetzt die Daten in meinem SQL-Server habe.

pv_db

Jetzt wo ich die Daten im SQL-Server gespeichert habe, brauche ich sie erstmal eine ganze Weile nicht. Denn der nächste Schritt sind dann Grundfunktionen der Oberfläche. Primär will ich wieder fit werden, was WPF betrifft und deshalb möchte ich mich nicht mit Datenbankproblemen herumärgern. Ich kann mich noch an einen ersten Gehversuch vor ein paar Jahren erinnern, da wurden erstmal alle Daten aus der Datenbank in den Speicher geladen, auch wenn sie garnicht gebraucht wurden. Sowas will ich an dieser Stelle vermeiden. Aus diesem Grund werden meine ersten Testversuche mit einem Dummy arbeiten, d.h. alle Daten liegen im Speicher. Aber das ist schon der zweite Schritt. Zu Beginn möchte ich einfach eine Startoberfläche haben, damit ich mit Icons herumspielen kann und vielleicht auch eine glückliche Farbkombination finden.

Von der Zeile zu Objekten

Jan 0

Und schon ist sie da - die nächste Folge zur Plattenverwaltung V4.0. Ich habe eigentlich die letzten Jahre darauf "verschwendet", an meinem Datenmodell zu feilen. Werfen wir aber zuerst mal einen Blick auf das aktuelle Datenmodell, wie es in Version 3.x eingesetzt wird. Ich speichere die Daten in einer Textdatei. Dort steht pro physikalischem Tonträger eine Zeile drin, d.h. für ein Doppelalbum wären das zwei Zeilen. Dabei reihen sich folgende Daten durch Paragraphenzeichen getrennt auf:

  • Interpret (bei Compilations steht hier "Verschiedene"
  • Name der Platte
  • Typ (Single, Maxi / EP, Maxi-CD, LP, CD, Compilation und CD-Compilation sind mögliche Werte)
  • Nummer des Tonträgers (z.B. bei Doppelalben 1 von 2)
  • Gesamtzahl der Tonträger
  • Label
  • Katalognummer
  • Herstellerland
  • Freitext (meistens enthalten: Ort und Datum wo ich das Ding gekauft hab)
  • Pfad zum Coverbild
  • Preis
  • Währung
  • Schalter, ob Titel vorhanden sind
  • Wie oft wurde der Tonträger im aktuellen Jahr abgespielt?
  • Wie oft wurde der Tonträger insgesamt abgespielt?
  • Anzahl der Titel
  • Jetzt folgen in Dreierpärchen: Interpret (nur bei Compilations gefüllt) / Titel / Länge des Titels

Daran war erstmal nicht viel fehlerhaft. Es gab nur einen tückischen Fehler: Wenn der Schalter, ob Titel vorhanden sind auf 0 stand, wurde der Tonträger nicht in den Charts berücksichtigt. Ansonsten habe ich versucht, so viele Ungereimtheiten zu entfernen, wie es nur irgend ging.

EntityDesignerDiagram

Schauen wir und das neue Datenmodell mal von unten nach oben an. Es beginnt mit dem Label, dass die Platten veröffentlicht. Früher war das mehr oder weniger Freitext, jetzt ist es normalisiert und ich habe die Chance zu sehen, welche Releases ich von welchem Label habe. Daran schließt sich der Release an. Unter Release verstehe ich die Zusammenfassung aller Tonträger die zu einer Veröffentlichung gehören, also z.B. das jetzt schon oft zitierte Doppelalbum. Ein Blick nach links zeigt und das Land, wo der Release herkommt. Folgt man in die Mitte des Bildes hängt dort Repräsentation der physischen Platte. Jede Platte kann ein Cover haben. Jetzt kommt eine Neuerung gegenüber dem alten Modell - ich habe gelernt, dass z.B. eine Maxi-CD eine Zusammenfassung von Typ und Medium war. In Zeiten des Downloads lade ich mir eine Maxi runter, die aber keine Schallplatte ist. Demzufolge musste eine Trennung her. Der Typ wäre jetzt "Maxi / EP" und das Medium "CD" oder "Vinyl" oder "Download". Für mich eigentlich eine der Verbesserungen in diesem Datenmodell.

Ganz rechts befinden sich die einzelnen Titel, die Interpreten zugeordnet sind, wie auch der Release einem Interpreten zugeordnet werden kann. Links oben habe ich jetzt Teile eingeführt, die ich zwar schon so gepflegt habe, aber nie richtig zugeordnet habe - den Kauf der Platte nach Ort, Wert und Währung. Es gibt dann auch noch das Jahr der Veröffentlichung separat - eine Verteilung der Platten nach Jahren lässt grüßen. Und zu guter letzt noch die Charts, die in Alltime-Charts und Jahres-Charts unterteilt sind. Neu ist hier das Datum des letzten Abspielen - so finde ich richtig alte Platten wieder. Was noch neu ist, ist der Name einer einzelnen Platte. Sammelboxen haben mich dazu gezwungen, z.B. wurde von Gas seine alten Werke unter dem Titel "Nah und fern" neu aufgelegt. Sie setzen sich zusammen aus den einzelnen Tonträgern "Königsforst", "Gas" usw.

Wie geht es jetzt weiter? Das Datenmodell ist da - jetzt müssen nur noch die Daten aus der Textdatei in den SQL-Server wandern, d.h. der nächste Schritt ist ein Datenkonvertierer, der die alte Datei nimmt, aufbereitet (gerade meine Einkäufe müssen von Freitext in sinnvolle Strukturen gebracht werden) und dann abspeichert. Dann kommt die unangenehme Aufgabe, dass ich die neu entstandenen Objekte bereinigen muss, d.h. "WARP", "Warp" und "Warp Records" müssen zusammengefasst werden. Wird wohl so laufen, dass ich die Korrekturen in der Textdatei vornehme und dann wieder von vorn einlese.

Plattenverwaltung 4.0

Jan 0

Ich muss mich mal etwas motivieren. Vor 7 Jahren habe ich mittlerweile davon geschwärmt eine neue Plattenverwaltung zu programmieren und bis jetzt ist nicht wirklich viel entstanden. Angefangen habe ich ja schon, aber immer wieder überlege ich, welchen Weg ich gehe - probiere ich eine Desktopanwendung, eine App für mein Smartphone oder doch eine PHP-gestützte Webanwendung? Aber so langsam bin ich dessen überdrüssig und will einfach eine Desktopanwendung, die meine Wünsche erfüllt. Welche das sind, will ich jetzt mal kurz vorstellen:

  • Charts - die so ziemlich am häufigsten genutzte Funktion. Ich möchte gerne wissen, welcher Tonträger wie oft insgesamt und pro Jahr abgespielt wurde. (Nice to have: Wissen, wann man den Tonträger zuletzt gehört hat.)
  • Suchen - hängt implizit in allen anderen Funktionen mit drin, aber derzeit scrolle ich mit dem Mausrad über 1.000 Tonträger rauf und runter, um den richtigen zu erwischen
  • Neue Tonträger anlegen
  • --- alles was jetzt kommt, brauche ich in der Regel nur selten ---
  • Tonträger bearbeiten - Tippfehler korrigieren, Daten nachtragen
  • Cover anzeigen
  • Tonträger löschen
  • Liste aller Tonträger ausdrucken
  • Statistiken
    • Gesamtwert, Gesamtlaufzeit bestimmen
    • Diagramm über Erscheinungsjahr und Anzahl der Tonträger

An mich die Herausforderung: Daten werden in einem SQL-Server abgelegt. Der Einfachheit halber greife ich auf die Datenbank mit ADO.NET zu. Oberfläche und die Logik und der ganze Kram entsteht mit C#. Fehlt nur noch der erste Schritt: Das Datenmodell. Lange Zeit habe ich mich damit herumgeschlagen. Zum einen muss meine alte Textdatei in die neue Struktur überführbar sein und zum anderen will ich mir nicht den Weg verbauen ggf. noch Erweiterungen zu schreiben.

April, April

Jan 0

Aprilscherze können billig sein, aber dieses Jahr hatten sie eine gewisse Klasse. Am besten gefiel mir, dass die ICANN die Rootserver des Internet für einen Tag abschaltet, weil alle IPV4-Adressen vergeben sind. Es ist zwar offensichtlich, dass man daran zweifelt, aber so verkehrt ist die Idee nicht. Und tauchte auch noch die Nachricht auf, dass man es ein Video über das letzte Experiment am LHC gibt, wo man Wissenschaftler sieht, die an einer nicht bekannten Konsole hantieren und man vermutet, dass damit schwarze Löcher aufgespürt werden sollen. Auch nicht von der Hand zu weisen. Aber Geschichten über Gebühren für E-Mails, die Umbenennung von Google waren schon zu offensichtlich.

Keine Fehlmeldung ist, dass Adobe an der Version 3 meiner "Weapon of choice" für einfache Fotobearbeitung arbeitet. Letztens ist die Beta von Lightroom erschienen und muss wohl einiges an nachträglicher Rauschunterdrückung mit sich bringen.

In den letzten Wochen war ich wieder viel unterwegs, Schulungen, Beratungsgespräche usw. Aber Schulungen laufen nicht ohne einen gewissen Grad von Humor, auch wenn er sehr spezifisch auf Programmierer gemünzt ist. So schnappte ich den Hinweis auf esoterische Programmiersprachen auf. Grund genug, da mal abends im Hotel etwas genauer zu forschen und festzustellen, dass es da wirktlich absonderliche Sachen gibt.

Drei Sprachen gefielen mir von der Idee so gut, dass ich hier mal ein paar vorstellen möchte. Fangen wir mit "Chef" an. Die Idee hinter Chef ist, dass programmieren doch nichts anderes ist, wie kochen. Man nimmt Zutaten, vermischt sie im richtigen Verhältnis und hofft, dass nichts anbrennt. Man schaue sich nur mal das Rezept für die "Fibonacci Zahlen begleitet von Karamelsauce" an - klingt nicht nur lecker, sondern berechnet nebenbei auch noch die ersten 100 Fibonacci-Zahlen.

PietManche behaupten ja auch Programmieren sei eine Kunst und deshalb sind Programmierer auch immer ein Stück Künstler. Und um ein richtiger Künstler zu sein, benutzt man eine Sprache, in der man sich nicht nur logisch, sondern auch grafisch verausgaben kann - Piet. Der Namensvetter für Piet war Piet Mondrian.

Für die etwas groberen, nicht künstlerisch begabten Programmierer, die sich vielleicht mit Taxifahren ihr Studium finanziert haben, ist Taxi die richtige Wahl. Für manche mag es ja wichtig sein, dass alles richtig funktioniert - bei Taxi ist es wichtig, dass die Daten am richtigen Platz landen. Und schon geht es los... "'Hello' is waiting at the Writer's Depot.
Go to Starchild Numerology: west 1st left, 2nd right, 1st left, 1st left, 2nd left."

Auch wenn es schon einen halben Monat her ist und seither Lena Meyer-Landrut wie eine Plage über die Charts herfällt, ich habe mir das Ausscheidungsspektakel für den Eurovision Song Contest angesehen. Zugegeben Lena polarisiert - entweder man mag sie oder überhaupt nicht. Ich schließe mich der "überhaupt nicht"-Kategorie an. Ich weiß nicht, ob ihr nervöses Gezappel gespielt oder real ist, genau ihre Rolle als kleines schüchternes Schulmädchen. Das hat schon damals Britney Spears auf Dauer keiner abgekauft. Aber kommen wir doch mal zum inhaltlichen Teil - sie kann nicht singen, hat keine Technik und zudem kommt "Satellite" auch noch komplett ohne Melodie aus. Hingegen zog Jennifer Braun mit ihrer Darbietung das Publikum, die Jury mit Ausnahme von Stefan "Ralph Siegel V2" Raab in den Bann. Selbst die Besucher der Eurovision Song Contest Seite verwiesen Lena auf Platz 3 - und an der Stelle mit einer konkreten Prozentzahl, die ich bei der Sendung vermisst habe. Was bleibt, ist der fade Geschmack einer getürkten Wahl und der Stoßseufzer, dass deutsche Musikohren endlich eigenen Geschmack entwickeln und ihn sich nicht vorgeben lassen.

Ich COMme

Jan 9

Heute wieder ein wunderschöner Beitrag aus der merkwürdigen Welt der Programmierung. Alles natürlich wieder am praktischen Beispiel erklärt. Angenommen ihr erhaltet Besuch (international, spricht viele Sprachen) und der schnüffelt in eurem Bücherregal herum, was natürlich überhaupt nicht nett ist. Statt zu fragen, vertauscht er die Reihenfolge, ändert Lesezeichen und macht Eselsohren hinein. Da er regelmäßig bei euch vorbeikommt, interessiert ihn natürlich meistens das Buch, was ihr gerade lest, seltener die anderen Bücher, aber das kommt schon mal vor.

Da gibt es nur einen Ausweg - den Bücherschrank absperren und ab sofort muss er euch fragen, was für ein Buch ihr gerade lest, von wem es ist, ob ihr mal eine Seite aufschlagen könnt bzw. wann und wo es erschienen ist usw. Damit hätten wir den theoretischen Teil abgehandelt und können zur Praxis übergehen. Da ihr ja aktive Lebenwesen seid (oder sind auch Zombies oder Untote unter meinen Lesern?), nennt sich das Ergebnis ActiveX. Ihr bereitet euch auf alle Fragen und Aktionen vor, die kommen könnten und stellt fest, dass es Ähnlichkeiten gibt.

Schlag mal Seite ... auf, von dem Buch, das du gerade liest! Schlag mal Seite ... auf, von dem Buch, das ... hieß!

Blöd wäre ja jetzt, wenn ihr für jede Frage oder Aktion, die neu angefordert wird, zwei neue Formulierungen aufschreiben müßtest. Das ist nicht nur aufwändig, sondern wird mit der Zeit auch ziemlich unübersichtlich. Also beschränkt ihr euch auf eine Formulierung, denn die Mehrzahl der Fragen richtet sich ohnehin nach dem Buch, das ihr gerade lest.

Schlag mal Seite ... auf, von dem Buch, das ... hieß!

Die zweite Hälfte der Aufforderung ist dabei freiwillig, d.h. wenn der Fragesteller den Teil weglässt, geht ihr einfach davon aus, dass es sich um das aktuelle Buch handelt, das ihr lest. Unter Programmierern wird soetwas optionale Parameter genannt. Jetzt kommt der Moment, wo wir das gesamte Wissen zusammenraffen können und an dem Punkt hängenbleiben, dass wir eine Fragestellung aufschreiben sollen, die auch noch international verständlich ist. Als Programmierer hat man es da einfach, denn für solche Zwecke wurde die Object Definition Language (ODL) erfunden, mit der man beschreiben kann, wie eine solche Frage aussieht - und im Endeffekt von vielen Programmiersprachen aus ansprechbar.

Natürlich kann man sich soetwas schnell zusammenklicken, aber an solchen Fragen, wie optionalen Parametern bleibt man doch hängen und muss von Hand eingreifen. So würde also die Aufforderung zum Aufschlagen einer Seite in ODL aussehen.

[id(42)] bool Aufschlagen(long Seite, [optional] VARIANT ISBN);

Das sollte doch auch für Nichtprogrammierer einleuchtend sein - ich gebe an, das ich Seite soundso aufschlagen möchte und wenn ich keine ISBN erhalte, nehme ich das aktuelle Buch. Natürlich versteht unsere ODL auch das Prinzip der Eigenschaften, in dem Fall Autor, Titel, Cover usw. Jetzt fängt der Vergleich mit den Büchern etwas zu hinken, denn die ODL ermöglicht uns nicht nur das Ermitteln, sondern auch das Verändern von Eigenschaften. Wäre ja möglich, in dem unser Besuch den Autor durchstreicht und seinen eigenen Namen darüber schreibt. Nur, dass er uns diesmal um Erlaubnis fragen muss.

Und jetzt treiben wir die Möglichkeiten der ODL auf die Spitze, denn das Object in ODL bedeutet, dass man eigentlich von einem Objekt ausgeht. Von diesem Standpunkt aus, sind optionale Parameter bei Eigenschaften doch etwas kniffliger. Also machen wir uns mal an die Beschreibung...

[id(42), propget] VARIANT Autor([optional] VARIANT param1); [id(42), propput] void Autor(VARIANT param1, [optional] VARIANT param2);

Um zu Verstehen, wie dicht wir hier am Limit der ODL arbeiten, brauch man sich nur mal die Parameter ansehen, denn die ODL besteht darauf, dass der erste Parameter jeweils den gleichen Namen hat, obwohl er bei der ersten Funktion (Ermitteln des Autors) inhaltlich der ISBN entspricht und im zweiten (Verändern des Autors) dem neuen Autor. Kommen wir aber zum schönen Teil - dem Einholen der Ernte.

Jetzt wird es natürlich extrem programmierlastig, aber die Kommentare sollten aufschlussreich genug sein.

// Verändern des Autors void CMyActiveX::SetAutor(const VARIANT FAR& param1, const VARIANT FAR& param2) {   // schauen wir mal nach, ob wir eine ISBN bekommen haben...   if (param2.vt == VT_ERROR && param2.scode == DISP_E_PARAMNOTFOUND)   {     // Keine ISBN, also nehmen wir das aktuelle Buch   }   else   {     // ISBN angegeben, also ein spezielles Buch suchen   } }

Erste Testergebnisse: Ich bin mit zwei Programmiersprachen auf die ActiveX-Komponente losgegangen und konnte (fast) problemlos damit arbeiten - einzig das Verändern von Eigenschaften mit optionalem Parameter machte in einer Sprache Ärger. Aber wir wollten es ja ohnehin nicht zulassen, dass die Gäste in den Büchern herumschmieren...

WordPress Cookie Hinweis von Real Cookie Banner