Freier Fall – revisisted

Den Fall eines Objekts kann man recht einfach mit Kameras festhalten und anschließend das Video in einzelne Bilder zerlegen. Während die Theorie des Freien Falls davon ausgeht, dass außer der Schwerkraft keine weiteren Kräfte wirken, wirkt sich in der Realität aber zumindest der Luftwiderstand aus. Im Film sieht man das an der wackelnden, kippeligen Bewegung des Muffinförmchens.

Muffinförmchen im freien Fall.

Mit Avidemux kann man das Video in einzelnen Bildern speichern. Untenstehend finden sich die Bilder Nr .10, Nr.20 und Nr.30 aus der Serie.

Alternativ kann man die Bildserien auch mittels Software herstellen, die von sich aus schon Bildsequenzen produzieren.

Wenn die Kamera mit 25 Frames pro Sekunde filmt, wird rund alle 40 ms ein Bild gemacht. Bild Nr. 10 entsteht also 10*40 = 400 ms = 0,4 s nach dem Start der Aufnahme. Zwischen den drei ausgesuchten Bildern besteht derselbe Zeitabstand, das Muffinförmchen legt aber vom zweiten zum dritten Bild einen weiteren Weg zurück.

Die vollständigen Daten in einer Tabelle. Zur Bestimmung des Ortes wurde der Mittelpunkt des verschwommenen Muffinförmchens gewählt.

t in sy in m
0.000.01
0.04-0.01
0.08-0.03
0.12-0.07
0.16-0.10
0.20-0.14
0.24-0.19
0.28-0.22
0.32-0.28
0.36-0.34
0.40-0.39
0.44-0.44
0.48-0.51
0.52-0.57
0.56-0.64
0.60-0.70
0.64-0.77
0.68-0.83
0.72-0.91
0.76-0.98
0.80-1.06
0.84-1.15
0.88-1.21
0.92-1.30
0.96-1.37
1.00-1.45
1.04-1.55
1.08-1.61
1.12-1.70
1.16-1.80

Die Spalten kann man anschließend in zwei Listen umwandeln. Das Ergebnis sieht dann im Bild aus, wie folgt.

In Rot die Daten von D. Brown, in Blau die Daten aus dem nachgestellten Experiment. Die Darstellung erfolgt mittels matplotlib.

Strukturierte Datenmengen

Zum weiteren Thema „Klima“ und „Klimawandel“ finden sich auf den Webseiten verschiedener Institute große, frei verfügbare Datenmengen. Kann man dadurch zu ähnlichen Einsichten kommen wie die Forscherin Johanna Beckmann im Video?

Das Modul numpy

Auf den ersten Blick können die Daten unüberschaubar wirken. Wenn sie sortiert sind und einzelnen Teilen bestimmte Datentypen erkennbar zugeordnet sind, wenn sie vielleicht sogar schon in Tabellenform vorliegen, kann man von strukturierten Datenmengen sprechen. Vergleichsweise leicht fällt der Zugang, wenn die Dateien vom Typ .csv oder .txt sind.

Um mit den Daten arbeiten zu können, muss man sie zunächst einlesen und anschließend auf Datensätze und einzelnen Daten zugreifen können. Zum Einlesen wird die Methode Numpy.genfromtxt() verwendet. Die Methode liest Tabellen aus Textdateien ein und erzeugt dabei ein Array mit allen Datenreihen und den einzelnen Elementen jeder Reihe.

data = Numpy.genfromtxt('datensammlung.csv', delimiter=',')
print(data) # ggfs. zur Überprüfung, ob die Daten angekommen sind. 
# -> [[1,2,3], [4,5,6], [7,8,9]]

Zugreifen kann man sowohl auf einzelne Elemente als auch auf Teilmengen, also quasi Reihen und Spalten. Jede Liste beginnt mit dem Index 0. Das bedeutet, auf das erste Element wird mit dem Index 0 zugegriffen.

data[0][0]    -> 1
data[1]       -> [4,5,6]
data[1][1:]   -> [5,6]
data[:,1]     -> [2,5,8] zweites Element jeder Reihe

Das Anlegen für Listen oder Arrays funktioniert in Python mit der Schreibung von Klammern. Das Hinzufügen von neuen Elementen durch append(Wert).

data[3] = []
data[3][0] = 10
data[3].append(11)
data[3] = [10,11,12]

Das vorgestellte Beispiel nochmals in Code.

Beispiel 1: Temperaturen am Südpol

Die Klimaänderung in den Polargebieten ist ein spannendes Fachgebiet. Die Temperaturen am Südpol sind erstaunlich, weil sie im Minusbereich einer großen Schwankung zwischen antarktischem Sommer und antarktischem Winter unterliegen. Die Daten stammen vom NCAR/UCAR National Center for Atmospheric Research.

Aufgabe

Stelle dar, wie sich die Jahresdurchschnittstemperatur in den verschiedenen Stationen der Antarktis seit Mitte des 20. Jhdts entwickelt hat.

[Lösung]

Beispiel 2: Eisdecke am Nordpol

Die Eisdecke am Nordpol hat eine Bedeutung für den Klimawandel, weil eine große Eisfläche mehr Sonnenlicht in den Weltraum zurückwirft als eine kleinere oder geschrumpfte Eisfläche. Es ist also bedenklich, wenn im Sommer mehr Eis schmilzt als im Winter neu entsteht. Anhand der frei zugänglichen Daten des National Snow and Ice Data Center bei der University of Colorado kann man solche Entwicklungen nachvollziehen.

Der folgende Programmcode stellt die Entwicklung des Wintereises (Januar) im Vergleich zum Jahresdurchschnitt dar.

Aufgabe

Binde die Entwicklung der Eisfläche im Sommer (August = Spalte 9) in das Diagramm ein.

[Lösung]

Zum Weiterlesen: Webseite des Potsdam-Instituts für Klimafolgenforschung.

Klimadaten

A) Temperatur

In Klimadiagrammen werden Durchschnittstemperaturen häufig mit Linien dargestellt. Möglicherweise steht bei vielen im Hintergrund die Vorstellung, dass Temperatur etwas ist, das mal da ist und mal nicht, sondern kontinuierlich zunimmt oder abnimmt. Das Diagramm enthält dann entlang der x-Achse 12 Abschnitte – für jeden Monat einen – und entlang der y-Achse die Temperaturscala. Trägt man die Durchschnittswerte eines Jahres ein, ergibt sich eine Darstellung, die charakteristisch für einen bestimmten Ort ist.

Aufgabe

Das folgende Skript basiert auf den Werten für die durchschnittliche Maximaltemperatur in Augsburg (Bayern).

  1. Füge eine zweite Liste Temperatur2 für die durchschnittliche Minimaltemperatur hinzu. Die nötigen Daten findest du auf den Seiten der Wetterdienste, z.B. hier: wetterdienst.de.
  2. Lass in einer anderen Farbe zusätzlich die zweite Datenreihe als Linie anzeigen.

Natürlich kannst du auch die minimalen und maximalen Temperaturwerte zu einem anderen Ort einsetzen.

Es gibt zwar keine mathematische Funktion, die einem Monat eine bestimmte Temperatur zuordnet, aber man kann trotzdem mit den Werten rechnen. Im Fall der minimalen und maximalen Werte ist es interessant, den Durchschnittswert für jeden Monat zu ermitteln. Für jeden Monat müssen dazu Minimal- und Maximalwert addiert und durch zwei geteilt werden.

temperatur3 sei []
Für jedes n von 0 bis ausschließlich 12 tue:
   d sei (temperatur[n] + temperatur2[n])/2
   füge d zu temperatur3 hinzu

Aufgabe

Berechne die Durchschnittstemperaturen, bilde daraus eine dritte Datenreihe und lass sie dir im Diagramm mit einer anderen Farbe anzeigen.

B) Niederschlag

Niederschlag kann es mal geben oder eben nicht. Sie sind in der Regel nicht kontinuierlich, sondern werden als bestimmte Menge zu einem Zeitabschnitt gemessen. Häufig wird daher die Niederschlagsmenge in Säulen dargestellt. Die folgende Darstellung basiert auf der monatlichen Durchschnittsmenge für Augsburg (Bayern).

Im Unterschied zur Methode matplotlib.pyplot.plot() wird hier die Methode matplotlib.pyplot.bar() verwendet. Der umgebende Code hat sich nicht wesentlich verändert.

Aufgabe

Lass eine zweite Datenreihe mit möglichst unterschiedlicher Ausprägung als kontrastierende Linie zu den Säulen zeichnen. Etwas anders stellt sich etwa der Niederschlagsverteilung in Los Angeles dar: Link.

C) Kombinierte Daten: Temperatur und Niederschlag

Wenn man unterschiedliche Daten in einer Ansicht kombinieren möchte, müssen diese zumindest eine Gemeinsamkeit haben. Im Fall der Klimadaten ist das der zeitliche Verlauf. Im folgenden Diagramm dient die Methode twinx() dazu, eine zweite Instanz einer Achse zu erzeugen, die synchronisiert mit der ersten einen weiteren Graphen zeichnen kann.

Aufgabe

  • Finde die Zeile im Code, an der eine weitere Achseninstanz erzeugt wird.
  • Beobachte, wie danach die Anweisung zum Zeichnen der Daten aufgerufen wird.
  • Ergänze die drei Datenreihen und korrigiere die beiden Label für die beiden y-Achsen.

Weiter: Strukturierte Datenmengen >>

Physikalische Daten

Geschwindigkeit

Die Bewegung von Körpern ist ein klassisches Gebiet der Physik. Zu bestimmten Zeitpunkten t wird der Ort eines Gegenstandes in Bewegung gemessen. Mit Smartphones kann man das sehr gut filmen und nachträglich zu festen Zeitabständen den Ort ermitteln. Bei Leifiphysik findet sich etwa die folgende Datenreihe:

t in s012345678910
x in m2020202020202326293235
Entnommen aus: Leifiphysik [Link]

Die Datenreihe kann man in einem Diagramm umsetzen. Dabei zeigt normalerweise die Achse für die Zeit (t) nach rechts und die Achse für den Weg (x) nach oben. Mit Matplotlib lässt sich das so darstellen:

Betrachtet man die Bewegung im Diagramm von Sekunde 5 bis Sekunde 10, erkennt man dass jeder Verlängerung der Zeit in diesem Bereich eine gleichartige Vergrößerung des Weges entspricht.

Aufgabe:

  1. Das Auto soll von Sekunde 10 bis 13 am gleichen Ort bleiben und danach wieder für 2 Sekunden zurückfahren. Ergänze die Datenreihen entsprechend und lass dir das Diagramm anzeigen.
  2. Die Gerade mit der gleichbleibenden Steigung ist im Diagramm gut zu erkennen und gleichbleibende Steigung bedeutet gleichbleibende Geschwindigkeit. Überlege: Was ist eigentlich am Knick, am Übergang von der liegenden Geraden zur ansteigenden Gerade?

Beschleunigung

Das Herunterfallen von Gegenständen gehört zu den alltäglichen Erlebnissen, seien es nun Äpfel, Schlüssel, Handys oder ganz andere Dinge. Messdaten zu fallenden Gegenständen kann man bekommen, wenn man den Vorgang vor einem Maßband filmt und anschließend die Einzelbilder des Films zu gleichen Zeitabständen betrachtet, um dann im Bild den jeweils zurückgelegten Weg zu bestimmen.

Die folgenden Daten sind bei einer Beobachtung der Bewegung aufgezeichnet worden:

t in msy in cm
33-43
67-54
100-70
133-113
167-145
200-204
234-253
267-312
300-387
334-462
367-543
Daten aus einem Beispiel zum Freien Fall von D. Brown [Link]

Betrachtet man den Graphen, kann man anfangs die Hälfte einer Parabel erkennen, bei der jedem gleichen Zeitabschnitt auf der t-Achse ein Vielfaches an zurückgelegtem Weg entspricht. Das geht so lange, bis die Krümmung in eine Gerade übergegangen und scheinbar eine gleichbleibende, maximale Geschwindigkeit erreicht ist. Diese Beobachtung der Bewegung führt zur Annahme, dass zumindest in der ersten Phase eine Kraft den fallenden Gegenstand immer weiter beschleunigt. Und dann?

Aufgabe

  1. Frag eine Physiklehrkraft deines Vertrauens, warum die Daten zur Bewegung eines fallenden Körpers diesen Graphen ergeben.
  2. Das Muffinförmchen wird zunächst nach Oben geworfen und fällt anschließend herunter. Ändere die Datenreihe entsprechend und lass dir das Diagramm anzeigen.

Projektidee

Eigentlich hast Du mit Deinem Smartphone und einem Metermaß alles, um selbst das Experiment durchzuführen und eigene Daten zu gewinnen.

Ein kleiner Ball, Krimskrams, Marmeladenbrote … Es fallen ja so viele Dinge recht schön. Filme den freien Fall des Objekts vor einem Metermaß. Du musst nicht unbedingt synchron starten; die Aufnahme kann schon laufen, während das Objekt noch gar nicht fällt. Lade den Film anschließend in einer Schnittsoftware, wähle anhand der Frames gleiche Zeitabstände und ermittle im Bild die gefallene Distanz: Fertig ist die Datenreihe. Jetzt nur noch im Programm laden und die Kurve anzeigen lassen. Zum Beispiel so: [Link]

Alternativ gibt es inzwischen Software für das Smartphone, die Aufnahmen in festen Zeitabständen erlaubt und dadurch Bewegungen quasi „einfriert“. [Link]

Links

  • Lineare Bewegung / Zeit-Ort-Diagramm bei Leifiphysik [Link]
  • Artikel s.v. „Freier Fall“, in: Wikipedia. [Link]
  • Einführendes Video [Link], Theorie zum Freien Fall bei Leifiphysik [Link].
  • Smartphone-Experiment mit phyphox [Link]

Weiter: Klimadaten >>

Funktionsgraphen

Einführung

Die grundlegende Idee von Funktionsgraphen ist es, dass mit derselben Vorschrift zu jedem x-Wert ein bestimmter y-Wert errechnet werden kann und dass sich dieser Zusammenhang in einer speziellen Graphik ausdrücken lässt.

f(x): x -> y = etwas, das mit x errechnet wird.

Mathematiker beschäftigt bei Funktionen z.B. die Frage, ob man eigentlich alles für x einsetzen darf oder aus welchem Bereich von Zahlen die Werte für y genommen werden. Aus Sicht der Informatik kann man die Menge der Werte, aus denen das x gewählt wird, unabhängig vom Inhalt als Liste betrachten, z.B. x = [-1,0,1,2,3,4,5,…]. Und auch die Menge der Werte, die sich aus der Anwendung der Verarbeitungsvorschrift in der Funktion ergeben, kann eine Liste sein. Es gilt insbesondere, dass für jedes xn in der Menge aller x ein bestimmtes yn errechnet werden kann. Kompliziert? Nein.

Beispiel lineare Funktion:
x sei [-1,0,1,2,3,4,5,...]; y sei anfangs [] 
Für jedes xn aus x tue: 
    yn = 1.5 * xn  # d.h.: führe die Funktion aus
    Füge yn zu y hinzu.
Gib y aus.
Code
Ergebnis
x-1012345
y-1,501,534,567,5
Wertetabelle für x = [-1,5] und y = 1.5*x

Praktische Vereinfachungen

Es gibt zu dieser Grundform noch zwei ganz praktische Vereinfachungen

  1. Die Funktion range
    range([int von,] int bis_ausschließlich [, float schritt]) -> Array erzeugt Zahlenmengen. Unbedingt nötig ist nur der zweite Parameter; so erzeugt range(11) eine Reihe von ganzen Zahlen von 0 bis 10, also mathematisch [0, 10] oder in Code [0,1,2,3,4,5,6,7,8,9,10]. Beachtenswert: range hat einen Rückgabewert, nur deswegen kann man schreiben
    x = range(-1,6)
  2. Listcomprehension ist eine besondere Fähigkeit von Python. Sie vereinfacht die Schreibweise bei der Verarbeitung von Listen, indem die For-Schleife in die Klammern für eine anfangs leere Liste gezogen wird. Mit x = range(-1,6) lässt sich so schreiben
    y = [1.5*xn for xn in x]
    Im Ergebnis ist y dann dieselbe Liste von Werten wie oben.

Eine Verallgemeinerung wäre es, wenn man die Verarbeitungsvorschrift in eine selbstdefinierte Funktion auslagert. So würde man für y = 1,5*x schreiben:

def func(x):
  y = 1.5*x
  return y

Mit x = range(-1,6) und der selbstdefinierten Funktion func ließe sich so schreiben
y = [func(xn) for xn in x]

Die beiden Listen x und y lassen sich anschließend wie im vorhergehenden Abschnitt „Punkte“ durch matplotlib zeichnen.

Aufgabe

Wende die beiden Vereinfachungen auf das untenstehende Beispiel an und lass dir das Diagramm anzeigen.

Weitere Funktionen

Mathematische Funktionen sind vielfältig. Mit x2 ergeben sich Parabeln, mit x3 monoton steigende Graphen 3. Grades, mit 1/x ergeben sich Hyperbeln. Im untenstehenden Beispiel wurde die Verarbeitungsvorschrift x -> y in eine selbstdefinierte Funktion ausgelagert.

Aufgabe

Experimentiere mit der Verarbeitungsvorschrift und versuche eine Parabel und eine Hyperbel zu erzeugen.

Weiter: Physikalische Daten >>

Punkte

Eine Menge von Punkten auf einem weißen Blatt Papier kann alles und nichts bedeuten.

Abb. 1: Drei Tropfen im Schnee?

Punkte in einem Kartesischen Koordinatensystem werden dagegen durch zwei Koordinaten bestimmt. Dabei ergibt sich der Wert jeder Koordinate als Abmessung auf einer zugeordneten Achse. Häufig sind das eine x-Achse (nach rechts) und eine y-Achse (nach oben), daher spricht man auch von x-Koordinate (1. Bestandteil) und y-Koordinate (2. Bestandteil).

Python verfügt mit matplotlib über ein Modul zur Darstellung von Punkten. Die Punkte A (-1/-2), B (1/1.5) und C (2/3) würden mit diesem Modul aussehen wie folgt.

Abb. 2: Die Punkte (-1/-2), (1/1.5) und (2/3) in einem Kartesischen Koordinatensystem

Die drei Punkte A, B und C kann man voneinander getrennt angeben: A (-1/-2), B (1/1.5) und C (2/3). Man kann sie aber auch in eine Wertetabelle eintragen:

ABC
x-112
y-21.53
Wertetabelle zu den Punkten A, B und C

Durch das Notieren der Punkte in einer Wertetabelle wird anschaulicher, dass durch die drei Punkte im Koordinatensystem eine Reihe von x-Werten einer Reihe von y-Werten zugeordnet ist. Diese Darstellung der x-Werte und y-Werte als Liste ist die Grundlage für das Zeichnen mit matplotlib.

Aufgabe

Versuche mit Punkten andere Darstellungen: ein Rechteck, ein Herz, eine Kurve, die Sonne mit Strahlen, …

Weiter: Funktionsgraphen >>

Visualisierung von Daten

Jede Stunde werden unvorstellbare Mengen an Daten produziert und alle Menschen, die sich über digitale Geräte vernetzen, tragen dazu bei. Um in einer vernetzten Welt kluge Entscheidungen zu treffen, muss man solche Daten analysieren und interpretieren können. Allerdings bestehen große Datenmengen häufig aus ungeordneten Zeichenketten oder aus unüberschaubaren vielen Zahlenreihen und für das Verständnis von beidem ist das menschliche Gehirn nicht besonders gut geeignet. Die Visualisierung von Daten kann da helfen, weil viele Menschen aus Bildern und gut aufbereiteten Graphiken komplexe Informationen häufig schneller entnehmen und leichter dazu Stellung beziehen können.

Johanna Schmidt (VRVis): Data Literacy und Datenvisualisierung [YouTube]

Die folgenden Seiten umkreisen das Themengebiet Visualisierung von Daten:

Weiterführende Links

  • David McCandless: The Beauty of Data Visualisization. Video von 2010 [Link], Website: Informationisbeautiful [Link], Webinar von 11-2020 [Link]
  • Was Sie über Big Data wissen müssen. Big Data Basics von Infineon [Link]
  • Niklas Steenfat: Wie wird man Data Scientist? Video [Link]

Referenzen und Tutorials

  • Python-Modul Matplotlib [Link]
  • Bernhard Grotz: Matplotlib – ein Plotter für Diagramme [Link]
  • Benjamin Aunkofer: Datenvisualisierung in Python [Link]
  • Bernd Klein: Numerisches Python [Link]
  • Gerd-Ludwig Ingold: Erstellung von Graphiken [Link]

Weiter: Punkte >>

Creative Commons Lizenzvertrag Dieses Werk ist lizenziert unter einer Creative Commons Namensnennung 4.0 International Lizenz.

Implementierung III: Steuerung und Interface

Nach den Klassen GELD, FACH und KASSE fehlt zum Schluss noch die Implementierung der Klasse KASSIERER. Diese Klasse soll den Vorgang des Kassierens abbilden, d.h. den Kundenkontakt, das Aufnehmen der Preise, das Entgegennehmen des gegebenen Geldes, das Berechnen des Wechselgeldes und das Zurückgeben von Restgeld. Idealerweise würde der Gesamtprozess ablaufen wie unten dargestellt.

Ablaufplan

Ablaufplan „Kassieren“

Fertiges Programm

Grundgedanke des fertigen Programms ist es, die Eingaben und Ausgaben über die Konsole zu simulieren. Es wäre ein weitergehendes Projekt, wen man die Eingabe mit einem Warenscanner und die Ausgabe über kleines Display darstellen wollte. Die beiden Schleifen im Ablauf, also die Wiederholung eines Vorgangs für jeden Kunden und die Wiederholung für jede Ware, die bereits Teil der Vorüberlegungen zur Modellierung waren, werden hier durch den wiederholten Aufruf von Methoden umgesetzt. Das gilt für start() und band().

Implementierung II: Operationen und Berechnungen

Eine Kasse besteht neben der Eingabe über Scanner oder Tasten und der Ausgabe in Form eines Displays aus einer Recheneinheit, und verschiedenen Geldfächern. Ein- und Ausgabe sollen zunächst vernachlässigt werden, weil sie Teil der späteren Benutzerschnittstelle sind. Damit bleibt zum einen als Eigenschaft der Kasse bestehen, dass sie verschiedene Geldfächer enthält. Zum anderen muss die Kasse verschiedene Rechenoperationen ausführen können, um dem Kassierer die Arbeit zu erleichtern. Die Kasse sollte:

  • Beträge summieren können,
  • die Bezahlung einlagern,
  • das nötige Wechselgeld errechnen können,
  • prüfen können, ob genug Wechselgeld vorhanden ist, und
  • das Wechselgeld bereitstellen.

Jeder der Forderungen steht eine Fähigkeit, also eine Methode der Klasse KASSE gegenüber:

Abb. 5: Klassendiagramm KASSE hat FACH hat GELD
A) Der Testfall

In einem Testfall soll die Kasse mit einer Menge an Wechselgeld gestartet werden. Anschließend werden Werte summiert und der Gesamtwert überprüft. Die Menge an Geld eines Faches wird abgefragt, bevor man einen bestimmten Geldbetrag einlagert; danach wird die Menge im Fach nochmals überprüft. Die Funktion test() müsste dann aufgerufen mit einer größeren Anzahl als Geldeinheiten im Fach sind False ergeben und bei einer geringeren Anzahl True. Schließlich sollte bereitstellen() die richtige Stückelung an Geldeinheiten zu einem Kommabetrag enthalten und die Menge der Geldeinheiten in einem bestimmten Fach um die richtige Anzahl reduzieren.

B) Grundlagen der nötigen Rechenoperationen

Die Methoden summiere(float betrag) und wechselgeld(float betrag) bestehen aus einer Addition bzw. einer Subtraktion von Kommawerten. Die Methoden einlagern(float betrag), test_wechsel(float betrag) und bereitstellen(float betrag) beruhen dagegen auf dem Berechnen der Anzahl von Geldeinheiten, die in einem Kommabetrag enthalten sind. So muss etwa bereitstellen(float betrag) abbilden, aus wie vielen unterschiedlichen Geldenheiten sich der Kommawert zusammensetzt.

Ganzzahlige Division int(a/b)

Wenn man mit Geldeinheiten rechnet, muss das Ergebnis einer Division immer ganzzahlig sein, weil eine Einheit entweder noch enthalten ist oder eben nicht mehr. So ist in 2,20 € genau ein 2 € Stück enthalten, aber nicht 2,2 Eurostücke. Das Ergebnis der Divison 2,20€ / 2€ muss also ein ganzzahliges Ergebnis liefern, also int(2,20/2).

Modulo (%)

Der Restbetrag der ganzzahligen Division ergibt sich am einfachsten durch eine Modulo-Operation. So ergeben 2,20 modulo 2 ebenso wie 4,20 % 2 die gewünschten 0,20, also genau den Restbetrag, der übrig bleibt, wenn man die nötige Anzahl an 2 Euromünzen bereits in Empfang genommen oder herausgegeben hat.

C) Berechung am Beispiel von test_wechsel(float betrag)

Der folgende Programmablaufplan stellt die nötigen Arbeitsschritte zum Überprüfen der Menge an Wechselgeld und ihren Zusammenhang dar.

Abb. 7: Ablauf in der Methode test(float betrag) -> boolean
def test(self, betrag):
# Wissen: return beendet die Ausführung einer Funktion
    # für jedes Geldfach tue
    for f in self.ReiheDerFaecher:
        # benötigte Stückzahl =
        #  ganzzahlige Division von 
        #  Betrag durch Wert des Geldes im Fach   
       menge = int(betrag / f.geld.get_wert())
        # Überprüfe ob die Sückzahl im Fach ist: 
        #              Nein? Gib zurück False       
       if not f.test(menge): return False
       # Neuer Betrag = Restbetrag 
       #     <= Betrag modulo Geldwert            
       betrag = round(betrag % f.geld.get_wert(), 2) 
    return True
    # Alle Fächer durchlaufen ohne Abbruch? 
    # Gib zurück True

Aufgabe:

Programmiere die fehlenden Methoden aus, so dass das Skript fehlerfrei abläuft und richtig funktioniert.

Weiter: Implementierung III: Steuerung und Interface >>

Implementierung I: Daten und Datenstruktur

Eine Implementierung des Modells nach dem Ansatz „Bottomup“ beginnt beim letzten Teil der von einander abhängigen Klassen bzw. Objekte, der Klasse GELD, und geht dann weiter zur Klasse FACH. Nachbesserungen sind denkbar.

a) Daten

Die grundlegenden Daten der Kassensimulation bestehen aus Geldmengen, also aus einer Zusammensetzung von verschiedenartigen Münzen und Scheinen. Die Eigenschaften von GELD sind ein Name (das Nominal), z.B. „1ct“, und ein entsprechender Wert wie 0.01. Der Wert drückt einen Bruchteil der angenommenen Einheit 1 € aus. Das bietet sich an, denn damit ist ein Umrechnungsfaktor unter den einzelnen Geldstücken gegeben. Je nach Programmiersprache benötigt die Klasse GELD keine besonderen Methode; im Beispiel wurden zur Demonstration zwei so genannte „Getter“ eingefügt.

b) Datenstruktur und grundlegende Methoden

Das Fach strukturiert die Geldmengen. Wenn also Geldmengen in der Situation die Daten sind, dann ist das Fach eine Datenstruktur. Jedes Fach der Kasse enthält eine gewisse Menge gleichartigen Geldes, also z.B. 35 der 1ct Münzen. Die Klasse FACH benötigt vier Methoden. Die Methode einlegen( anzahl int ) erhöht die Menge an Geld im Fach; die Methode herausgeben( anzahl int ) reduziert die Menge. Die Methode summe() -> float gibt den aktuellen Betrag aller im Fach enthaltenen Münzen zurück. Die Methode test( menge int ) -> boolean überprüft, ob die Anzahl der enthaltenen Geldstücke oder Geldscheine ausreicht, um eine bestimmte Menge zurückzugeben.

c) Komposition
Abb. 4: Klassendiagramm „FACH hat GELD“

Die Methoden der Klasse Fach lassen sich mit den Methoden einer Liste vergleichen. Die Enthält-Beziehung kann man durch zwei Attribute – Menge und Geld – oder über eine Liste der Geldeinheiten implementieren. Die Liste bietet sich an, wenn man den Geldeinheiten eine ID geben möchte, ansonsten reicht auch ein Objekt der Klasse GELD und die Angabe der Menge, wie viele Objekte davon im Fach liegen. Diese Eigenschaft rückt GELD in die Nähe von Bitcoin und ähnlichen virtuellen Währungssystemen.

Aufgabe

  1. Die Methoden einlegen() und summe() der Klasse FACH sind bereits fertig implementiert, programmiere in ähnlicher Weise die Methoden herausgeben() und test(). Beachte, dass test() im Unterscheid zu herausgeben() einen Rückgabewert besitzt.
  2. Schreibe ein geeignetes Testprogramm, das überprüft, ob die Klasse FACH funktioniert.
  3. Überlege: Welche Möglichkeiten gäbe es, eine eindeutige ID für jede Geldeinheit zu erzeugen?

Veranschaulichung von FACH.summe()

Abb.5: Der Ablauf, wenn die Methode FACH.summe() aufgerufen wird.

Die grauen breiten Linien im Hintergrund stellen Teile des Skripts dar. So verweist die Linie FACH.summe() auf den Ort im Skript, wo diese Methode definiert ist und die nötigen Anweisungen stehen, also auf die Zeilen 35 bis 38. Die roten und gelben Pfeile geben die Abfolge der Ausführung wieder. Der Sprung geld.get_wert() geschieht zur Laufzeit in Zeile 37. Sobald der erforderliche Wert da ist, also zurückgegeben wurde, kann die Summe berechnet und dieser Betrag seinerseits zurückgegeben werden. Vgl. dazu Zeile 38.

Weiter: Implementierung II: Operationen und Berechnungen >>