Von Stiften und Mäusen
Stifte und Mäuse

Eine Einführung in die Grundlagen der objektorientierten Programmierung

umgesetzt für die Programmiersprache Python von
Ingo Linkweiler
i.linkweiler@gmx.de
Universität Dortmund

Erstellt: 01.09.2002, letzte Änderung: 26.03.2003


Inhalt:

1 Einleitung
2 Installation
3 Besonderheiten
4 Beispiele
5 Schlusswort

Klassendokumentation

1 Einleitung:

Dieses Dokument geht davon aus, dass Grundlagen der Programmiersprache Python bereits bekannt sind, und das Skript
Von Stiften und Mäusen - Eine Einführung in die Grundlagen der objektorientierten Programmierung
Erste Auflage 1999
Landesinstitut für Schule und Weiterbildung, Soest
Durckverlag Kettler GmbH, Bönen
ISBN 3-8165-4165-8

oder:

http://www.learn-line.nrw.de/angebote/oop/
bekannt ist. In diesem Text wird die Installation und Anwendung der Python-Umsetzung beschrieben, und auf Besonderheiten eingegangen.


2 Installation:

Benötigt wird:
Solange Python 2.3 noch in der Alpha-Version ist, empfehlen wir die 2.2er Version zu installieren.

Vorbereitung (Windows-Version):

1.) Installieren Sie über die Setup-Funktion Python.

2.) Installieren Sie PyGame.

3.) Installieren Sie den Editor, und konfigurieren Sie den Editor so, dass der Python-Interpreter (Python.exe) mit den erstellten Skripten aufgerufen werden kann: Dies geschieht beispielsweise unter ConTEXT :

Einstellung -> Umgebungseinstellung -> Benutzerbefehle , Hinzufügen: Endung "py".
Dann unter "Ausführen" die "Python.Exe" Datei auswählen, und unter "Parameter" eintragen: "-i %n". %n steht für den Dateinamen, und die Option -i weist den Interpreter an, nach Programmende weitere Eingaben zu erlauben.


Nun kurz die Einstellungen des Editors testen:

Im Editor eingeben:
print "hallo welt"
Diese Datei speichern als "hello.py"

Dann F9 oder den kleinen "Kopf-"Button für "Benutzerbefehl1" drücken, der Python-Interpreter sollte starten und obiges Programm ausführen. Hat bis hierhin alles funktioniert, ist der Python-Interpreter installiert und der Editor korrekt eingestellt.
Der Interpreter wird mit "Strg+Z" beendet.

4.) Installation der Software Von Stiften und Mäusen:

Erstellen Sie ein Verzeichnis für die eigenen Quelltexte (z.B. \Eigene Dateien\Quelltexte, und entpacken (z.B. mit Winzip) den Inhalt der Archiv-Datei SuM.zip in dieses Verzeichnis.
Somit ist SuM einsatzbereit.

Zum ersten Test sollten Sie (durch Doppelklick) das Programm setupandtest.py starten, es testet die Installation und nimmt noch einige Anpassungen vor. Wählen Sie hier die GUI-Konfiguration nur, wenn Sie eine integrierte Umgenung wie beispielsweise PyWin oder IDLE verwenden. In unserer vorgeschlagenen Umgebung mit Context sind die GUI-Anpassungen NICHT nötig.

Dann können Sie einige der Beispielprogramme öffnen und starten, beispielsweise demo_ball.py.

Die Installation ist hiermit abgeschlossen.

3 Besonderheiten:

Abweichend zur Vorlage des Skriptes hat die Python-Version folgende Besonderheiten:
  1. Der Wechsel-Zeichenmodus wurde nicht implementiert, da er auf modernen Grafikkarten mit hoher Farbtiefe Probleme bereiten kann. Zum Zeichnen bewegter Objekte muss also mit dem Radiermodus gearbeitet werden, oder die neue Sprite-Klasse verwendet werden.
  2. Zahlreiche Beispiele im Skript verwenden bewegte Objekte, welche aufwendig über Stift-Methoden gezeichnet (und wieder gelöscht) werden. Zur Vereinfachung wurde eine neue Klasse Sprite eingeführt, um Bilder und bewegte Figuren zu zeichnen. Die Figuren sind Grafikdateien, welche zuvor in einer beliebigen Bildbearbeitungssoftware erzeugt werden können.

4 Anwendungsbeispiele:

Im Folgenden wird auf die konkrete Umsetzung nach Python eingegangen. Es liegen einige Beispielanwendungen bei (bezeichnet mit demo_*.py), welche teilweise an die Beispiele aus dem Skript angelehnt sind.

Beispiel demo_wagen.py:
Lernziel: Einfache (imperative) Methodenaufrufe, Nutzung der Zeichenmethoden.
Aufgabe: Es soll ein einfacher Wagen gezeichnet werden.

Im folgenden wird der Quelltext kurz erläutert:

Zunächst müssen bei allen Programmen die nötigen Klassen importiert werden. Anfang sind dies die Klassen "bildschirm" und "stift", später kommen "tastatur", "maus", "anwendung", "ereignisanwendung" hinzu. (siehe Klassendokumentation)

 Der Einfachheit halber wird immer die Variante "from modulname import *" verwendet.

from sum import *

Nun müssen Instanzen der Klassen "Bildschirm" und "Stift" erzeugt werden, dies geschieht durch Zuweisung an eine Variable:

# Erzeuge Bildschirm und Stift
meinBildschirm=Bildschirm()
meinStift=Stift()


Nun können Methoden der erzeugten Objekte aufgerufen werden:

# Zeichne Wagen
meinStift.bewegeBis(x,y)
meinStift.runter()
meinStift.zeichneRechteck(28,10)
meinStift.hoch()
meinStift.bewegeBis(x+5,y+10)
meinStift.runter()
meinStift.zeichneKreis(3)
meinStift.hoch()
meinStift.bewegeBis(x+20,y+10)
meinStift.runter()
meinStift.zeichneKreis(3)
meinStift.bewegeBis(x+28,y+5)
meinStift.zeichneRechteck(2,2)

Abschliessend werden die Objekte meinStift und meinBildschirm wieder entfernt (=freigegeben):

meinStift.gibFrei()
meinBildschirm.gibFrei()


Den Schülern sollte hier eine Übersicht aller Methoden der Klassen Bildschirm, Stift, Maus und Tastatur als Hilfsmittel gegeben werden, das Auswendiglernen der Methodennamen soll nicht Ziel des Unterrichts sein. Der Umgang mit den Zeichen-Methoden sollte mit einigen einfachen Aufgaben geübt werden. Zur Variation bietet sich die Instanziierung zweiter Stifte an: Damit kann das Verständnis des Stiftes als eigenes Objekt erklärt werden. Erfahrungsgemäß verstehen Schüler oft den Unterschied zwischen Instanz (bzw. Objekt) und Klasse (als Beschreibung) nicht.

Beispiel demo_maus1.py:
Lernziel: Schleifen (while) und Fallunterscheidungen (if), sowie der "nicht"-Operator (not)

# Beispiel: Nutzung der Klassen Bildschirm, Maus und Stift
# Einführung der Schleife mit while

from sum import *

# Erzeuge Bildschirm und Stift
bildschirm=Bildschirm()
stift=Stift()
maus=Maus()
stift.runter()

while not maus.istGedrueckt():
  stift.bewegeBis(maus.hPosition(),maus.vPosition())

maus.gibFrei()
stift.gibFrei()
bildschirm.gibFrei()


Die Beispiele demo_maus2.py und demo_maus3.py führen Fallunterscheidungen mit if ein und demonstrieren die Nutzung der Tastatur.
Im Skript sind zahlreiche Ideen Beispiele (Ampel, Schatzsuche ...), um das Erlernte in Aufgabenform umzusetzen.

Beispiel demo_ball.py:
Lernziele:
Einfache Animation durch abwechselndes Löschen (Radieren), verändern der Position und Zeichnen an der neuen Position.
Benutzung von Variablen zur Speicherung der Position.

Beispiel demo_ball2.py:
Lernziel: Bisher wurden nur "fertige" Klassen und Methoden verwendet. Nun soll das Erstellen von Klassen mit Attributen und Methoden eingeführt werden. Dazu wird zunächst ein "Modell" des Balls erstellt: Welche wichtigen Eigenschaften und Möglichkeiten soll der Ball haben? (mindestens x,y-Position, x,y-Richtung. Weitere Ideen: Farbe, Groesse, Gewicht....). Nun wird die Klasse als Modellbeschreibung eingeführt (Attribute und Methoden). Der Ball bekommt einen eigenen Stift: Damit lassen sich später verschiedenfarbige Bälle erzeugen. In das Modellieren sollte viel Zeit investiert werden und die Umsetzung an weiteren Beispielen geübt werden. Hier sollte auch das Erzeugen mehrerer Instanzen eines Objekts besprochen werden, z. B. durch Erzeugen von zwei oder mehr Bällen (aus nur einer Klassenbeschreibung)

# Beispiel: Definition einer Klasse Ball
from sum import *

# Definition eines Balls

class Ball:
def __init__(self):
self.xPosition=100
self.yPosition=100
self.xRichtung=4
self.yRichtung=2
self.stift=Stift()

def gibFrei(self):
# Freigeben macht nichts
self.stift.gibFrei()

def zeichne(self):
# Einen Ball an der aktuellen x/y-Position zeichnen
self.stift.hoch()
self.stift.bewegeBis(self.xPosition,self.yPosition)
self.stift.runter()
self.stift.zeichneKreis(10)

def bewege(self):
# mich selbst "wegradieren"
self.stift.radiere()
self.zeichne()

# mich bewegen
self.xPosition=self.xPosition+self.xRichtung
self.yPosition=self.yPosition+self.yRichtung

# Wenn der Ball den Rand erreicht, die Richtung ändern.
if self.xPosition>600:
self.xRichtung=-4
if self.xPosition<20:
self.xRichtung=4
if self.yPosition<20:
self.yRichtung=2
if self.yPosition>400:
self.yRichtung=-2

# mich zeichnen
self.stift.normal()
self.zeichne()


# Erzeuge Bildschirm und Stift
bildschirm=Bildschirm()
maus=Maus()
tastatur=Tastatur()

# Erzeuge ein Objekt "Ball"
ball=Ball()
ball.zeichne()

# Ball bewegen bis Mausklick
while not maus.doppelKlick():
ball.bewege()

# Und Ende.
tastatur.gibFrei()
maus.gibFrei()
bildschirm.gibFrei()

Die spezielle Methode "__init__" wird automatisch beim Erzeugen eines Objekts aufgerufen. Sie kann benutzt werden, um Attribute mit vorgegebenen Werten zu belegen. Die Attribute müssen zwar nicht explizit definiert werden, es bietet sich aber an, in "__init__" alle verwendeteten Attribute mit Werten zu belegen. Der Parameter "self" wird bei der Definition der Methoden immer als erster Parameter angegeben. Dies soll kennzeichen, dass das Objekt selbst innerhalb der Methode unter dem Namen "self" zur Verfügung steht. Beim Aufruf der Methode wird dieser Parameter nicht explizit angegeben.

Im Hauptprogramm wird mit
ball=Ball()
eine Instanz aus der Klasse Ball erzeugt. Dieser Aufruf entspricht dem Aufruf von "erzeugen" aus dem Skript. Dabei wird gleichzeitig die Methode __init__ aufgerufen, und somit werden die Attribute auf ihre Vorgabewerte gesetzt. Jetzt können die Methoden des Objekts verwendet werden:
ball.bewege()
wird solange aufgerufen, bis durch einen Rechts bzw. Doppelklick die Schleife verlassen wird.

Beispiel Demo_Mühle.py
Das Beispiele Demo-Mühle.py wird eine Klasse zum Zeichnen einer bewegten Windmühle definiert.
In Demo-Mühle2.py wird diese Klasse so geändert, dass die Mühle nun einen eigenen Stift erhält (vgl. Skript)

Beispiel Demo_Buntball.py
Lernziel: Spezialisierung
Das bekannte Ballbeispiel wird erweitert: Durch Spezialisierung wird aus der Klasse Ball ein farbiger Ball (buntball) erzeugt.

Beispiel Demo_zug_alt.py
Lernziel: Definition neuer Klassen durch Spezialisierung.
Zunächst wird eine allgemeine Klasse Waggon definiert.
Darauf werden Klassen Lok, Personenwagen und Gueterwagen abgeleitet.
Die Methode "koppelan" erhält als Parameter ein Objekt, hier wird erstmals ein Attribut eines  übergebenen Objekts von einem anderen Objekt genutzt.
Diese "alte" Variante benutzt den Stift, um den Zug zu zeichnen. Um einen "schönen" Zug zu ohne Aufwand zu erstellen, folgt nun eine Variante mit Sprites:

Beispiel Demo_zug_neu.py
wie oben. Statt den Zug selbst zu zeichnen, werden Sprites genutzt, um ein fertiges Bild zu laden. Parameter sind der Name des Bildes:
self.bild=Sprite("wagen-gueter.bmp")
Das Zeichnen erfolgt automatisch, sobald die Methode setzePosition(x,y) aufgerufen wird.

Beispiel Demo_zug_mit_nachfolger.py
Jeder Waggon bekommt nun ein Attribut Nachfolger.  Die Methode "bewege_um" bewegt den Wagen selbst, und seinen Nachfolger.
Es muss nun nur noch die Lok bewegt werden.  Die Methode "Kopple_an" teilt dem Vorgänger den Nachfolger mit (Prinzip der Verkettung)

Beispiel Demo_auto.py
Lernziel: Erzeugen mehrerer Instanzen eines Objekts
Nutzung einer Schleife mit Tastaturabfrage zur Steuerung der Autos

Beispiel Demo_autosprite.py
Das gleiche Programm wie zuvor. Die neue Klasse Sprite erlaubt die Benutzung von vorbereiteten Bildern. Somit können die doch recht quelltextintensiven Zeichenmethoden entfallen. Erstmals ist hier ein Attribut selbst ein Objekt, daher kommt hier die "doppelte" Punkt-Notation zustande:
self.bild=Sprite("auto.bmp")
self.bild.setzePosition(100,100)
Beispiel Demo_autosprite_2.py
Erneut das altbekannte Programm. Die Klasse Auto ist nun als Spezialisierung der Klasse Sprite realisiert.

Beispiel Demo_autosprite-ereignisanwendung.py
Hier wird das Konzept der "Ereignisanwendung" demonstriert.

5 Schlusswort

Ich hoffe, diese Beispiele geben genug Anregungen für eine Umsetzung im Unterricht.
Sehr viele Anregungen und Musteraufgaben gibt es hier:
http://www.learn-line.nrw.de/angebote/oop/medio/kurs/einfuehrung/index.html


Ingo Linkweiler