Benutzer-Werkzeuge

Webseiten-Werkzeuge


en:examples

Dies ist eine alte Version des Dokuments!


Inhaltsverzeichnis

Exampes

EAN check

The EAN check is an example of a simple GUI application. It has an entry component for entering an EAN and a text component for the multi-line output of results.

This event method is programmed for the „Check“ button:

def bCheck_Command(self):
    # Input
    EAN = self.EANTV.get()
    # Processing
    if not EAN.isdigit():
        self.output('An EAN must not contain any characters from digits!')
    if len(EAN) == 13:
        self.output('Length of EAN: 13 ')
        self.output('Entered check digit: ' + EAN[12])
        sum = 0
        index = 0
        factor = 1
        while index < 12:
            sum = sum + int(EAN[index])*factor
            index = index + 1
            if factor == 1:
                factor = 3
            else:
                factor = 1
        if sum % 10 == 0:
            calculatedCheckDigit = 0
        else:
            calculatedCheckDigit = 10 - sum % 10
        if int(EAN[12]) == calculatedCheckDigit:
            self.output('The check digit ' + EAN[12] + ' is correct!')
        else:
            self.output('The entered check digit ' + EAN[12] + ' is incorrect!')
            self.output('The correct check digit is ' + str(calculatedCheckDigit))
    else:
        self.output('The entered EAN has ' + str(len(EAN)) + ' digits!')
        self.output('It must consist of 13 digits.')

According to the IPO principle, the input from the entry component is read in first. The text variable EANTV assigned to the entry component is used for input or output. Its value can be read with ENATV.get() for input and with EAN.set(value) for output. With

    EAN = self.EANTV.get()

the EAN entered in the Entry component is read into the local variable EAN of type str(ing) and can then be processed.

The processing part checks whether 13 digits have been entered and then performs the check digit calculation.

Outputs are made to the text component labeled Output. It has very powerful methods, so even just outputting a line isn't quite easy. A separate method output() is therefore used in order to simplify programming.

def output(self, line):
    self.Output.insert('end', line + '\n')

This inserts a line at the end of the text component Output and ends it with the control character '\n' (NewLine). If an output line consists of several substrings, these must be put together with „+“. Numbers must first be converted into a string using str().

Download:

Car

This example is suitable for the introduction to object-oriented programming. Fuel gauge and mileage of a car are modeled. The actual modeling takes place with the class modeler. The license plate is not absolutely necessary, it is used to make it easier to distinguish between cars and to use another data type.

The result can be tested interactively in the UML window. The students understand the difference between the concepts class and object.

In the next step, the car class is used as a functional spezification in a GUI program.

The GUI program uses the car class. To do this, it must be imported. A car is created and provided as attribute car1 of the GUI class for further use.

    from car import *
      ...
      self.car1 = car('DA RR 1013', 47, 7.3)

When refueling, the quantity entered in the entry component is read in via the get() method of the text variable eRefuelTV belonging to the component and converted into the required data type using float.

    def bRefuel_Command(self):
        # Input from the GUI
        amount = float(self.eRefuelTV.get())
        # Processing
        self.car1.refuel(amount)
        # Output
        self.show()

Then, according to the IPO principle, the entered amount is processed in the refuel() method.

Finally, the result is output with a separate method show(). The values for tank contents and mileage are retrieved via the get() methods get_tankcontent() and get_mileage() of the class car and passed to the set() methods of the text variables eTankcontentTV and eMileageTV:

    def show(self):
        self.eTankcontentTV.set(self.car1.get_tankcontent())
        self.eMileageTV.set(self.car1.get_mileage())
        self.lCar.place(x = self.car1.get_mileage(), y = 160)

The label component lCar has been assigned a car image via the Image attribute in the object inspector. The place() method sets the x position of the car to the mileage.

Download

Linked List

Die Programmierung dynamische Datenstrukturen stellt eine erhebliche Herausforderung dar, denn man muss das Konzept der Verkettung mittels Verweisen verstehen und komplexe Operationen mit Verweisen druchführen. Neu dabei sind Variablen die Werte haben, welche Verweise auf Objekte bzw. Adressen sind.

In diesem Beispiel betrachten wir eine einfach verkettete lineare Liste. Die Liste selbst wird als Klasse VerketteteListe modelliert mit Knoten als Listenelementen. Als Attribut hat sie einen Verweis auf den Anfang der Liste.

Die Klasse Knoten kann im ersten Attribut Daten speichern kann und im Attribut Nächster den Verweis auf einen nächsten Knoten der verketteten Liste. Hat ein Knoten keinen nächsten Knoten, so erhält dieses Attribut den Wert None.

class Knoten:
    def __init__(self, Daten):
        self.Daten = Daten
        self.Nächster = None

Die Implementierung einer Einfügeoperation ist schwierig, weil vier Fälle zu unterscheiden sind:

  1. Die Liste ist leer.
  2. Es soll am Anfang eingefügt werden.
  3. Es soll am Ende eingefügt werdenn.
  4. Es soll zwischen zwei Knoten eingefügt werden.

Die beiden ersten Fälle lassen sich mit der Methode einfügen_AmAnfang() implementieren:

    def einfügen_AmAnfang(self, einKnoten):
        einKnoten.Nächster = self.Anfang
        self.Anfang = einKnoten

Im UML-Fenster lässt sich die Implementierung testen. Dazu erzeugt man eine verkettete Liste und einen Knoten, ruft über das Objekt verketteteliste1 die Methode einfügen_AmAnfang() auf und gibt für den Parameter einKnoten den Wert knoten1 an.

Zum Einfügen am Ende der Liste muss man sich mit einer Schleife und einer Cursor-Variablen zum letzten Element durchhangeln. Dort wird der neue Knoten angefügt.

    def einfügen_AmEnde(self, einKnoten):
        if self.Anfang is None:
            self.Anfang = einKnoten
        else:
            Cursor = self.Anfang
            while Cursor.Nächster is not None:
                Cursor = Cursor.Nächster
            Cursor.Nächster = einKnoten

Am schwierigsten ist das Einfügen vor einem Knoten, denn der neue Knoten muss dann hinter dem vorhergehenden Knoten eingefügt werden. Neben dem Cursor braucht man dazu einen weiteren Verweise auf den vorherigen Knoten. Der Knoten vor dem einfügt werden soll wird durch seine Daten bestimmt.

    def einfügen_vor(self, Daten, einKnoten):
        if self.Anfang.Daten == Daten:
            self.einfügen_amAnfang(einKnoten)
            return
 
        vorheriger_Knoten = self.Anfang
        Cursor = vorheriger_Knoten.Nächster
        while Cursor is not None and Cursor.Daten != Daten:
            vorheriger_Knoten = Cursor
            Cursor = Cursor.Nächster
        if Cursor is not None:
            einKnoten.Nächster = Cursor
            vorheriger_Knoten.Nächster = einKnoten
        else:
            raise Exception("Knoten mit Daten '%s' nicht gefunden" % Daten)

Vergleichbar schwierig ist das Löschen eines Knotens, denn zum Löschen muss der vorherige Knoten mit dem nachfolgenden verbunden werden.

    def löschen(self, Daten):
        if self.Anfang.Daten == Daten:
            self.Anfang = self.Anfang.Nächster
        else:
            vorheriger_Knoten = self.Anfang
            Cursor = vorheriger_Knoten.Nächster
            while Cursor is not None and Cursor.Daten != Daten:
                vorheriger_Knoten = Cursor
                Cursor = Cursor.Nächster
            if Cursor is not None:
                vorheriger_Knoten.Nächster = Cursor.Nächster

Durch interaktives Testen im UML-Fenster kann man die Funktionsfähigkeit der implementierten Methoden sehr gut prüfen, denn das Ergebnis wird unmittelbar im Objektdiagramm visualisiert. Man erkennt sofort, ob eine Methode wie gedacht funktioniert hat. Im Bild wurde zum Testen der löschen()-Methode die Liste mit den Elementen 'a, 'b' und 3 erzeugt und dann der Knoten mit Daten = 'b' gelöscht. Das hat funktioniert, denn die Liste besteht nur noch aus den beiden Elementen 'a' und 3.

Download:

en/examples.1643706663.txt.gz · Zuletzt geändert: 2022/02/01 10:11 von roehner