Dank der Erlaubnis von Ingo Linkweiler ist es mir nun möglich, dass Stifte-und-Mäuse-Paket für Python unter der Creative Commons Lizenz by-nc-sa zu veröffentlichen. Damit schnüre ich hier nun ein Paket zusammen, welches zum einen die Orginial SuM-Dateien (mit neuem Lizesierungshinweis), als auch die Grafikzeichnererweiterung inklusive PyObjVG-Modul enthält. Während die genannten Bausteine alle unter der Creative Commons Lizenz veröffentlicht sind, wird der SVG-Import durch das ElementTree-Toolkit mit gesonderten Lizenzbedingungen zur Verfügung gestellt.
PyObjVG Version 2.0
Im Rahmen eines universitären Projektes habe ich ein Python-Modul entworfen, welches Schülerinnen und Schülern ermöglicht, mit Hilfe von Python Vektorgrafiken zu erstellen. Dabei wurde keine grafische Benutzungsschnittstelle erzeugt, wie sie Vektorgrafikprogramme wie Inkscape benutzen, sondern ein Klassenkonzept zum Erzeugen von grafischen Primitiven, welche nur über passende Python-Befehle gesteuert wird.
Schülerinnen und Schüler müssen also beim Erzeugen eines Bildes Kenntnisse von den Attributen und Methoden der verschiedenen Klassen haben, als auch die syntaktischen Regeln der Programmiersprache Python einhalten.
Um der fehlenden Anschaulichkeit dieser Art und Weise der Grafikerzeugung entgegenzuwirken, sind zwei Erweiterungen vorgesehen.
- Der Im- und Export von SVG-Dateien
Dies ist zum einen die einzige Möglichkeit der Speicherung konstruierter Grafiken (neben in Python eingebauten Methoden zu Serialisierung von Objekten), zum anderen ist damit eine Brücke zur Darstellung von Daten mit Hilfe von XML gezeigt. Da gängige Browser einen Großteil der SVG-Spezifikation darstellen können, ist zumindest eine Anschaulichkeit des Konstruktionsergebnis gegeben.
Während der SVG-Export recht einfach zu Implementieren war, stellt sich der SVG-Import als sehr komplex dar, weil die Möglichkeiten von PyObjVG im Vergleich zu SVG sehr reduziert sind. Der SVG-Import muss daher in weiteren PyObjVG Versionen stark überarbeitet bzw. überprüft werden. - Zeichnen mit Hilfe der Stifte-und-Mäuse-Bibliothek (vgl. Blog-Eintrag)
Es wurde neben dem PyObjVG-Modul, welches ein in sich geschlossenes System zur Datenrepräsentation darstellt, eine Erweiterung für die Stifte-und-Mäuse-Bibliothek (in der Python-Desktop-Version nach Ingo Linkweiler) implementiert, welches Vektorgrafikobjekte des PyObjVG-Moduls interpretiert und entsprechende Zeichenroutinen aufruft. Diese neue „Grafikzeichner“-Klasse ist angepasst an das Signalweiterleitungskonzept des PyObjVG-Moduls und kann daher zur automatisierten Verfolgung des Aussehen der Vektorgrafik genutzt werden.
Das Projekt ist noch nicht beendet. Neben einer kleinen ToDo-Liste im Speziellen für den SVG-Import wurden noch keine größeren Testläufe durchgeführt. Ein spezieller Punkt für die Zukunft, der hier noch anzumerken ist, ist derjenige, dass ich ebenfalls an einer Schnittstelle für die Stifte-und-Mäuse-Bibliothek auf Mobiltelefonen arbeite. Da zum Jahreswechsel eine erste Version einer Portierung der Pygame-Bibliothek für PyS60 Systeme veröffentlich wurde, werde ich diese vor der Überarbeitung meiner Alpha-Version noch testen, vielleicht bieten sich dort verbesserte Möglichkeiten.
Zur Nutzung von PyObjVG auf Desktopsystemen werden folgende Teile benötigt.
Update: Nach Änderung der Lizenzbedingungen (vgl. Blog-Eintrag) nun als Paket verfügbar.
static-Attribute in C++ Klassen
An dieser Stelle soll die Aussage
„Statische Klassenattribute müssen außerhalb der Klassendefinition initialisiert werden.“
ein wenig näher untersucht werden. Betrachtet sei dazu die folgende Klassendefinition:
class KlasseMitStaticElement {
public:
static int anzahl;
KlasseMitStaticElement() {
cout << "Konstruktor aufgerufen" << endl;
KlasseMitStaticElement::anzahl++;
}
};
Geht man nun nach der oben genannten Regel vor, so würde die naive Initialisierung (eigentlich eine Zuweisung, siehe Zusatz unten) so aussehen: KlasseMitStaticElement::anzahl = 0;
. Leider resultiert diese Zeile in einen Kompilerfehler, es wird über das undefined symbol „KlasseMitStaticElement::anzahl“ gemeckert. Faszinierenderweise gelingt die Initialisierung aber mit int KlasseMitStaticElement::anzahl = 0;
warum?
Dazu müssen Deklaration, Definition und Initialisierung Begrifflich sauber voneinander getrennt werden. Ich verweise dazu auf ein C++-Forum, in dem von Benjamin Kaufmann folgendes geschrieben ist:
- Deklaration: Ein Programmausdruck der einen Namen in einen Scope ein- bzw. wiedereinführt.
- Definition: Eine Deklaration die die Details einer Entität bekannt macht oder, im Fall von Variablen, die dazu führt, dass Speicher für die Entität reserviert wird. Eine Deklaration einer Klasse (struct, class, enum, union) Funktion oder Methode wird zu einer Definition, wenn auf die Deklaration ein in geschweiften Klammern eingeschlossener Block folgt.
Variablendeklarationen sind immer auch Definitionen es sei denn, der Deklaration ist ein extern vorangestellt. - Initialisierung: Eine Definition mit expliziter Anfangswertzuweisung.
Nach obigen Versuchen stellen wir also fest, dass auch die Voranstellung von static im Klassenkontext dazu führt, dass eine ursprüngliche Definition nur eine Deklaration darstellt. In dem Beispielprogramm matstatic.zip habe ich als statisches Attribut keinen einfachen Datentyp genutzt, sondern eine Klasse mit Standardkonstruktor verwendet. So kann man sehen, dass die Definition der Variable nach der Klassendefinition dazu führt, dass der Standardkonstruktor aufgerufen wird.
Bezogen auf das obige Beispiel stellt man also fest, dass die explizite Initialisierung (und damit implizite Definition) der Variable anzahl
nicht notwendig ist. Eine Definition wie int KlassenMitStaticElement::anzahl;
wäre ausreichend, da die integer-Variable damit automatisch vom Compiler mit 0 initialisiert wird.
Ob die automatische Initialisierung einen allgemeinen C++-Standard oder nur eine Laune meines Compilers darstellt, ist mir zwar nicht bekannt — eventuell kann ohne Anfangszuweisung der Schwachsinn, der vorher an der Speicherstelle der Variable stand, von uns weiter genutzt werden — aber die anfangs erwähnte Aussage muss korrigiert werden.
„Statische Klassenattribute müssen außerhalb der Klassendefinition DEFINIERT werden.“
Zusatz:
Über Initialisierungen zu sprechen, stellt sich als nicht ganz einfach heraus, da das Verhalten des Compilers nicht nur von der Anweisung selbst, sondern auch von ihrer Position im Quelltext abhängt. Eine implizite Initialisierung mit 0 wird für die Anweisung int a;
als globale Definition vorgenommen, während die gleiche Anweisung im Funktionskontext einen undefinierten Wert für a behält.
Man könnte nun auf der einen Seite eine implizite und eine explizite Initialisierung unterscheiden (nach der Definition aus dem Forum wäre nur die explizite Initialisierung überhaupt eine Initialisierung), oder man geht dem Problem aus dem Weg, indem man jede Variablendefinition auch gleichzeitig mit einer expliziten Initialisierung im Quelltext versieht. Da nur Variablen mit eindeutig zugewiesenen Werten semantischen Sinn ergeben, kann man die ganz oben genannte Aussage als Merkregel sehr gut für die Praxis verwenden. Doch sollten wir ein wenig verallgemeinern:
„MERKREGEL: Alle Variablen müssen initialisiert werden. Bei statischen Klassenattributen geschieht dies außerhalb der Klassendefinition.“
Lustige Operatorensuche in C++ (Koenig Lookup?)
Bei der Korrektur von Übungsblättern zu einer C++ Vorlesung bin ich auf das folgende, auf den ersten Blick sehr simple Phänomen gestoßen: Da definiert mir doch jemand eine friend Methode innerhalb der Klasse. Wohlgemerkt nicht nur eine Deklaration, sondern eine ganz Implementation. Ausschnittsweise sieht das nun wie folgt aus:
class Koordinaten
{
...
friend ostream& operator<<( ostream& os, const Koordinaten& out );
{
os << "X-Koordinate: " << out.x << endl ;
os << "Y-Koordinate: " << out.y << endl ;
os << "Z-Koordinate: " << out.z << endl ;
return os ;
}
};
Naja, hübsche Idee, das wird definitiv nicht kompilieren — dachte ich mir. Schief gewickelt. Klappt sogar sehr gut. Aber warum?
Bisher dachte ich, nach friend darf gar keine Definition folgen. Gut, deklariert man eine Methode an mehreren Stelle (z.B. Aufteilung in hpp und cpp Dateien), dann könnte es doch eigentlich egal sein, an welcher Stelle die Implementierung steh. Aber ganz ohne Deklaration außerhalb der Klasse hätte ich nicht vermutet, dass C++ diesen Operator überhaupt findet.
Naja, im Rahmen einiger Recherchen zu den verschiedensten C++-Phänomenen bin ich auf die Homepage von Benjamin Kaufmann gestoßen. Er schildert in seiner C++ FAQ in kurzer und knapper Weise das Prinzip des Koenig Lookup und wenn ich mich nicht völlig verdreht habe, dann könnte gerade dieses die Lösung zur Operatorensuche (bzw. zum Phänomen des Findens) sein. Betrachtet man nämlich den zweiten Punkt
ist T eine Instanz einer Klasse/Struktur X, kommen alle Namensräume hinzu, in denen X definiert wird.
dann interpretiere ich mal die Klasse als Namensraum, welcher automatisch durchsucht wird, da als Parameter des Operators ein Objekt dieser Klasse vorkommt.
Neben der Tatsache, dass ich natürlich eine solche Definition nicht gutheiße, da sie ziemlich verwirrend ist, wollte ich meine Erkenntnisse einfach einmal mitteilen, denn bisher dachte ich, dass soetwas abgefahrenes überhaupt nicht möglich sei.
Zusatz:
Habe von Benjamin Kaufmann eine kleine Erklärung bekommen, die meine Gedanken zu der Problematik bestätigt. Es sei hier nur noch der Hinweis angebracht, dass das Koenig Lookup auch argument dependent lookup genannt wird und dazu sogar eine kleine Seite in der Wikipedia existiert (zumindest auf Englisch) http://en.wikipedia.org/wiki/Argument_dependent_lookup
Stifte und Mäuse mit Python unter MacOSX
Die unter Learn-Line angebotene Implementierung der Stifte und Mäuse Bibliothek ist – ganz im Widerspruch zum einleitenden Satz „Sie finden hier die Klassenbibliothek von Stifte und Mäuse für verschiedene Betriebssysteme und Programmiersprachen.“ – nur auf die Programmiersprache Java zugeschnitten. Ingo Linkweiler hat in seiner Diplomarbeit die alternative Programmiersprache Python für den unterrichtlichen Einsatz näher analysiert und in diesem Zusammenhang ebenfalls eine Implementierung der Stifte und Mäuse Bibliothek in eben dieser Sprache erstellt. Leider liegt die Fertigstellung dieser Quellen schon einige Zeit zurück, der Einsatz mit Python 2.5.2 mit meinem Mac stellte sich als nicht ganz so einfach dar. Hier daher eine kurze Beschreibung, wie ich bis zur problemlosen Benutzung vorgegangen bin:
- Installation von Python 2.5.2 über http://www.python.org/download/ (Für die vorinstallierte Version funktioniert die Installation von PyGame nicht)
- Installation von PyGame über http://rene.f0o.com/~rene/stuff/macosx/ (dabei Hinweis beachten, dass auch pyobjc installiert werden muss)
- Download der Stifte und Mäuse Quellen von Ingo Linkweiler. Durch eine Umstellung von Python fehlt jetzt allerdings zu Beginn jeder Quelldatei die Angabe der verwendeten Kodierung. Mit einem kleinen Bash-Script habe ich die verwendete Latin1-Kodierung angegeben.
- Das Ausführen der test.py klappte nun leider noch nicht, es ergab folgenden Fehler (Auszug):
*** Assertion failure in -[SDL_QuartzWindow setTitle:]
Die Fehlermeldung zeigt schon ein wenig in die Richtung, die ich durch ein wenig herumprobieren gefunden habe. In der Datei sumwrapper.py wird in Zeile 197 die Überschrift für das Bildschirmfenster festgelegt. Der Umlaut „ä“ ist dabei problematisch. Die Änderung in „ae“ hat diese Fehlermeldung beseitigt.
Das Ergebnis kann in der Datei sum.zip heruntergeladen werden.
Textverarbeitungen, dumm und ineffizient
Als jemand, der seit seinem Erstkontakt zu LaTeX, beständig versucht, Textverarbeitungen (insbesondere Microsoft Word) möglichst zu vermeiden, fand ich die Ausarbeitung mit dem provokanten Titel >>Textverarbeitungen sind dumm und ineffizient<< unheimlich angenehm zu lesen. Mein Tipp: Artikel lesen und LaTeX ausprobieren, es gibt (fast) keine Gründe, die dagegen sprechen!
LaTeX Online
Habe eben hier einen Online-Übersetzer für LaTeX-Quelltexte entdeckt. Auf den ersten Blick eine grundsätzlich schöne Einrichtung. Ich habe aber so schnell noch nicht herausgefunden, welche Pakete auf dem zugrundeliegenden TeX-System installiert sind, leider gibt es nämlich keine Rückmeldung, wenn ein Fehler im Quelltext ist. Zumindest nicht bei der Ausgabe als PDF, und das ist die einzige, die ohne weiteres bei mir im Browser (Safari) funktioniert hat.
LaTeX-Vorlesung
Habe an der Universität Kassel eine Vorlesung zu LaTeX gefunden. Hätte bis heute nicht gedacht, dass man dazu eine Vorlesung halten kann. Naja, können schon, aber ich dachte, dass die Benutzung von solchen Tools (Grafische Büroprogramme eingeschlossen) immer als eine der Qualifikationen gesehen wird, die man sich als Student „so nebenbei“ anzueignen hat.
Die Materialien, insbesondere natürlich das Vorlesungsscript (Folien), sind sehr interessant zu überfliegen. Natürlich keine ausformulierte Anleitung, jedoch viele Stichworte, die einem den Zugang zu LaTeX erweitern/erleichtern können.
Sehr interessant fand ich z. B. den Hinweis auf die case-Umgebung, die stückweise definierte Funktionen im Mathemodus erheblich erleichtert. Auf jeden Fall einmal einen Blick wert.
Die Programmiersprache R
Im Rahmen eines Seminars habe ich mich heute auf die Suche nach Software zur Stochastik gemacht. Als erstes viel mir die Programmiersprache „R“ ein, eine OpenSource Variante der Sprache „S“, von der ich bisher nur wusste, dass sie existiert, nicht, wie man sie nutzen kann.
Eine kleine Einführung in die Statistik (unter Berücksichtigung der Sprache „R“) von Dr. Andreas Handl könnt ihr hier herunterladen. Auf der einen Seite finde ich es didaktisch nicht unbedingt wertvoll, auf welche Art und Weise man hier an die Sprache herangeführt wird, auf der anderen Seite finde ich die Sprache selbst auch nicht gerade ansprechend, für den Einsatz in Schulen – vor allen Dingen in der Unterstufe – in meinen Augen nicht geeignet.
Aber macht euch selbst ein Bild.
Kryptographie Workshop
Im Rahmen der 7. sächsischen Informatiklehrerkonferenz wurde von Günther Glatzel ein Kryptoworkshop ausgearbeitet. Auf den ersten Blick eine sehr gute Idee, im hohen Maße fächerübergreifend informatische Bildung zu vermitteln. Bei der Suche nach näheren Informationen zum Autor bin ich auf die Linkliste zum Thema Kryptographie auf der Seite des Werner-von-Siemens-Gymnasium in Berlin gekommen.