Montag, 6. Juni 2011

 

Listings - Source Code drucken

Es sollte m.E. doch möglich sein, Listings in der folgenden - lesbaren - Form zu erzeugen:
Die Schrift ist leserlich, die Zeilen richtig eingerückt, Dateiname und Autor etc. sind ersichtlich (Ich gebe zu, dieses Bild ist schlecht...). Verwendet wurde recode und a2ps unter Linux. 
Wichtig ist auch, dass man allgemeine Programmierrichtlinien befolgt.
Aber mit Office kann man auch sehr schöne Listings erzeugen:
Man muss nur Kopf- und Fußzeilen einrichten, die Schrift auf Courier New (9 oder 10pt) oder eine andere mit fixer Breite und dann zwei Seiten auf eine drucken.
Ähnliches gibt es schon unter Listings (Source-Code drucken) zu lesen.

Stattdessen bekommt man so etwas.

Der Sourcecode ist unmöglich zu lesen, weil die Einrückung bald die dargestellte Zeilenlänge erreicht. Die Schriftgröße ist aber zumindest OK.

Schlimm ist aber das folgende Listing, da würden 4 Code-Seiten auf einem Blatt Platz haben. Trotzdem sind es aber nur 2 Seiten pro Blatt. Die Schrift ist unleserlich klein.

Das ist eine Zumutung!

Labels: , , , , ,


Mittwoch, 27. April 2011

 

Beispiele zu Gleitkommadarstellung (POS1: 1B)

Hier finden Sie ein paar Übungsbeispiele zu Gleitkommazahlen sowie die dazugehörige Lösung. Zunächst Konvertierung von Dezimalzahlen in Gleitkommazahlen. Es sind die Zahlen immer alle drei Formate zu bestimmen:

-0,15087890625
Nachkommateil:
0.15087891 | 0
0.30175781 | 0
0.60351562 | 1
0.20703125 | 0
0.41406250 | 0
0.82812500 | 1
0.65625000 | 1
0.31250000 | 0
0.62500000 | 1
0.25000000 | 0
0.50000000 | 1
Gesamt: 1 ,00100110101                (die 1 steht für das Vorzeichen -)
Mantisse wäre: 1001101010
Exponent wäre: -2
Exponent umwandeln:
         2 | 0
         1 | 1
Exponent unbeschränkt positiv: 10
Exponent mit führenden Nullen: 0010
Zweierkomplement:
   Einerkomplement:            1101
                                  1
   Zweierkomplement:           1110
Exponent: 1110, Vorzeichen: 1

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
1  1  0  0  1  1  0  1  0  1  0  1  1  1  1  0 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
1  1  1  1  1  0  1  0  0  1  1  0  1  0  1  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
1  1  1  1  0  1  1  0  0  1  1  0  1  0  1  0 

33
ganzzahliger Teil:
        33 | 1
        16 | 0
         8 | 0
         4 | 0
         2 | 0
         1 | 1
Nachkommateil:
Gesamt: 0 100001,                (die 0 steht für das Vorzeichen + - beachte den Abstand)
Mantisse wäre: 1000010000
Exponent wäre: 6
Exponent umwandeln:
         6 | 0
         3 | 1
         1 | 1
Exponent unbeschränkt positiv: 110
Exponent: 0110, Vorzeichen: 0

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
0  1  0  0  0  0  1  0  0  0  0  0  0  1  1  0 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
0  0  0  1  1  0  1  0  0  0  0  1  0  0  0  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
0  0  1  1  0  0  1  0  0  0  0  1  0  0  0  0 

470,171875
ganzzahliger Teil:
       470 | 0
       235 | 1
       117 | 1
        58 | 0
        29 | 1
        14 | 0
         7 | 1
         3 | 1
         1 | 1
Nachkommateil:
0.17187500 | 0
0.34375000 | 0
0.68750000 | 1
0.37500000 | 0
0.75000000 | 1
0.50000000 | 1
Gesamt: 0 111010110,001011
Mantisse wäre: 1110101100
Exponent wäre: 9
Exponent umwandeln:
         9 | 1
         4 | 0
         2 | 0
         1 | 1
Exponent unbeschränkt positiv: 1001
Exponent: 1001, Vorzeichen: 0

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
0  1  1  1  0  1  0  1  1  0  0  0  1  0  0  1 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
0  0  1  0  0  1  1  1  1  0  1  0  1  1  0  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
0  1  0  0  1  0  1  1  1  0  1  0  1  1  0  0 

-17,2145
ganzzahliger Teil:
        17 | 1
         8 | 0
         4 | 0
         2 | 0
         1 | 1
Nachkommateil:
0.21450000 | 0
0.42900000 | 0
0.85800000 | 1
0.71600000 | 1
0.43200000 | 0
0.86400000 | 1
0.72800000 | 1
0.45600000 | 0
0.91200000 | 1
0.82400000 | 1
0.64800000 | 1
0.29600000 | 0
0.59200000 | 1
0.18400000 | 0
0.36800000 | 0
0.73600000 | 1
0.47200000 | 0
0.94400000 | 1
Gesamt: 1 10001,001101101110100101
Mantisse wäre: 1000100110
Exponent wäre: 5
Exponent umwandeln:
         5 | 1
         2 | 0
         1 | 1
Exponent unbeschränkt positiv: 101
Exponent: 0101, Vorzeichen: 0

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
1  1  0  0  0  1  0  0  1  1  0  0  0  1  0  1 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
1  0  0  1  0  1  1  0  0  0  1  0  0  1  1  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
0  0  1  0  1  1  1  0  0  0  1  0  0  1  1  0 

-0,015625
ganzzahliger Teil:
Nachkommateil:
0.01562500 | 0
0.03125000 | 0
0.06250000 | 0
0.12500000 | 0
0.25000000 | 0
0.50000000 | 1
Gesamt: 1 ,000001
Mantisse wäre: 1000000000
Exponent wäre: -5
Exponent umwandeln:
         5 | 1
         2 | 0
         1 | 1
Exponent unbeschränkt positiv: 101
Exponent mit führenden Nullen: 0101
Zweierkomplement:
   Einerkomplement:            1010
                                  1
   Zweierkomplement:           1011
Exponent: 1011, Vorzeichen: 1

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
1  1  0  0  0  0  0  0  0  0  0  1  1  0  1  1 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
1  1  1  0  1  1  1  0  0  0  0  0  0  0  0  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
1  1  0  1  1  1  1  0  0  0  0  0  0  0  0  0 

12739
ganzzahliger Teil:
     12739 | 1
      6369 | 1
      3184 | 0
      1592 | 0
       796 | 0
       398 | 0
       199 | 1
        99 | 1
        49 | 1
        24 | 0
        12 | 0
         6 | 0
         3 | 1
         1 | 1
Nachkommateil:
Gesamt: 0 11000111000011,
Mantisse wäre: 1100011100
Exponent wäre: 14
Exponent umwandeln:
        14 | 0
         7 | 1
         3 | 1
         1 | 1
Exponent unbeschränkt positiv: 1110
Exponent: 1110, Vorzeichen: 0

vm m  m  m  m  m  m  m  m  m  m  ve e  e  e  e  
0  1  1  0  0  0  1  1  1  0  0  0  1  1  1  0 

vm ve e  e  e  e  m  m  m  m  m  m  m  m  m  m  
0  0  1  1  1  0  1  1  0  0  0  1  1  1  0  0 

ve e  e  e  e  vm m  m  m  m  m  m  m  m  m  m  
0  1  1  1  0  0  1  1  0  0  0  1  1  1  0  0 

Zurückrechnen

Gegeben sind die Zahlen im 2. Format, m = 9 und e = 3:
0 0 1 0 1 1 1 1 1 1 0 0 0 0
Beide Vorzeichen positiv
Mantisse: 1111100002
positiver Exponent: 1012 = 510
Zahl in normierter Gleitkommadarstellung: 0,111112 * 25 = 111112
Ergebnis: 31

1 0 1 1 1 1 1 0 0 1 0 1 0 1
Vorzeichen der Mantisse negativ, daher ist die Zahl negativ
Mantisse: 1100101012
positiver Exponent: 1112 = 710
Zahl in normierter Gleitkommadarstellung: -0,1100101012 * 27 = 1100101,012
Ergebnis: -101,25

1 1 1 1 0 1 0 0 1 1 0 1 0 1
beide Vorzeichen negativ, daher ist die Zahl negativ und der Exponent negativ
negative Mantisse: -1001101012
negativer Exponent, daher Zweierkomplement des Exponenten: 0102 = -210
Zahl in normierter Gleitkommadarstellung: -0,1001101012 * 2-2 = 0,001001101012
Ergebnis: -0.15087890625
(Vergleichen Sie das mit dem Ergebnis des Beispiels ganz oben!)

Zahlenbereich

Die Formel aus der Schulübung:

Eingesetzt für B = 2 (Binärsystem), m = 10 (von ganz oben) und e = 4 (von ganz oben):

Labels:


Donnerstag, 10. März 2011

 

Lösungen zu "Übungsbeispiele zu Sequenzen, Schleifen und Funktionen in Python" (POS1: 1B)

Hier mögliche Lösungen zu der Aufgabe "Übungsbeispiele zu Sequenzen, Schleifen und Funktionen in Python (POS1: 1B)". Einige der Aufgaben enthalten Suchaufgaben. Die Funktionen dazu sind teilweise nicht "strukturiert" programmiert, das heißt, dass sie in diesen Fällen nicht nur ein return sondern mehrere Ausgänge haben. Um das zu verdeutlichen, beachten Sie folgendes Beispiel:
def isint(string):
    """prüft, ob der String eine ganze Zahl ist (Vorzeichen optional, 
    nur Ziffern).
    Prüfe nur Ziffernbereich."""
    if len(string) > 0:
        if string[0] == '+' or string[0] == '-':
            for c in string[1:]:
                if c < '0' or c > '9':
                    return False
        else:
            for c in string:
                if c < '0' or c > '9':
                    return False
    else:
        return False
    return True
Hier erfolgt ein return False aus den Schleifen über den String string, sobald ein Fehler gefunden wurde. Das vereinfacht den Algorithmus, widerspricht aber der strukturierten Programmierung, die bei Funkionen nur einen Ausgang erlaubt (bei Schleifen gilt das auch, die Schleife verlässt man nur durch die Schleifenbedingung, nicht durch break oder eben return). Beim Debuggen größerer Systeme ist es von Vorteil, wenn man sich darauf verlassen kann, dass jede Funktion nur einen Ausgang hat, denn man braucht dann nur diesen einen beobachten und nicht mehrere.
Bei obigem Beispiel müsste man while-Schleifen verwenden:
def isint(string):
    """prüft, ob der String eine ganze Zahl ist (Vorzeichen optional, 
    nur Ziffern).
    Prüfe nur Ziffernbereich."""
    ok = True
    if len(string) > 0:
        if string[0] == '+' or string[0] == '-':
            i = 1
            while ok and i < len(string):
                if string[i] < '0' or string[i] > '9':
                    ok = False
                i += 1
        else:
            i = 0
            while ok and i < len(string):
                if string[i] < '0' or string[i] > '9':
                    ok = False
                i += 1
    else:
        ok = False
    return ok
Diese Variante könne man noch "vereinfachen", weil sich die beiden Zweige mit oder ohne Vorzeichen nur im Startwert der Laufvariable i unterscheiden:
def isint(string):
    """prüft, ob der String eine ganze Zahl ist (Vorzeichen optional, 
    nur Ziffern).
    Prüfe nur Ziffernbereich."""
    ok = True
    if len(string) > 0:
        if string[0] == '+' or string[0] == '-':
            i = 1
        else:
            i = 0
        while ok and i < len(string):
            if string[i] < '0' or string[i] > '9':
                ok = False
            i += 1
    else:
        ok = False
    return ok
Die "nicht strukturierte" Variante ist aber bei weitem schneller entwickelt und durch die automatischen Tests ist auch sichergestellt, dass sie funktioniert.

Die Tests verwenden assert(), um die Ergebnisse mit den erwarteten Ergebnissen zu vergleichen. assert() bricht das Programm auf der Stelle ab, wenn die Bedingung nicht erfüllt ist. Dadurch hat man die Möglichkeit, den Fehler einzugrenzen. Passt die Bedingung, so läuft das Programm einfach weiter.

"""
author: Haberstroh, Harald
matnr:  d09666
file:   sequenzenbeispiele.py
desc:   Beispiele einfacher Funktionen mit Sequenzen (vgl. Programmierblog)
        Einige Funktionen bauen auf den anderen auf.
        
        Zu jeder Funktion (ausgenommen Hilfsfunktion) gibt es eine Testfunktion
        die die jeweilige Funktion mit Testwerten prüft.
        
        Die Funktion assert() prüft den Wahrheitswert des Parameters. Ist dieser
        True, so läuft das Programm einfach weiter. Ist er jedoch False, wird
        das Programm mit einer Fehlermeldung und Zeilennummer abgebrochen.
        Man kann dadurch feststellen, welcher Test nicht funktioniert hat.
date:   7.3.2011
class:  Lehrer
catnr:  33
"""
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isint(string):
    """prüft, ob der String eine ganze Zahl ist (Vorzeichen optional, 
    nur Ziffern).
    Prüfe nur Ziffernbereich."""
    if len(string) > 0:
        if string[0] == '+' or string[0] == '-':
            for c in string[1:]:
                if c < '0' or c > '9':
                    return False
        else:
            for c in string:
                if c < '0' or c > '9':
                    return False
    else:
        return False
    return True

def test_isint():
    assert(isint("") == False)
    assert(isint("a") == False)
    assert(isint("1a") == False)
    assert(isint("a1") == False)
    assert(isint("1+1") == False)
    assert(isint("1+") == False)
    assert(isint("1") == True)
    assert(isint("+1") == True)
    assert(isint("-1") == True)
    assert(isint("11212") == True)
    assert(isint("-11212") == True)
    assert(isint("+11212") == True)
    print("test_isint() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isintb(string, basis):
    """prüft, ob der String eine ganze Zahl zur Basis basis ist (Vorzeichen
    optional, nur Ziffern).
    Baue String mit gültigen Zeichen zusammen und prüfe dann, ob jedes
    Zeichen in diesem String vorkommt."""
    if basis > 1:
        gueltig = "" # "Liste" der gültigen Zeichen für geg. Basis
        if basis > 10: # Ziffern und Buchstaben (immer groß und klein)
            for z in range(10):
                gueltig += chr(z + ord('0'))
            for z in range(basis - 10):
                gueltig += chr(z + ord('a')) # Kleinbuchstabe
                gueltig += chr(z + ord('A')) # Großbuchstabe
        else: # nur Ziffern
            for z in range(basis):
                gueltig += chr(z + ord('0'))
        if len(string) > 0:
            if string[0] == '+' or string[0] == '-': # Vorzeichen
                for c in string[1:]:
                    if c not in gueltig:
                        return False
            else:
                for c in string:
                    if c not in gueltig:
                        return False
        else:
            return False
    else:
        return False
    return True # alles OK

def test_isintb():
    assert(isintb("", 2) == False)
    assert(isintb("a", 2) == False)
    assert(isintb("1a", 2) == False)
    assert(isintb("a1", 2) == False)
    assert(isintb("1+1", 2) == False)
    assert(isintb("1+", 2) == False)
    assert(isintb("1", 2) == True)
    assert(isintb("+1", 2) == True)
    assert(isintb("-1", 2) == True)
    assert(isintb("11212", 2) == False)
    assert(isintb("-11212", 2) == False)
    assert(isintb("+11212", 2) == False)
    assert(isintb("11212", 3) == True)
    assert(isintb("-11212", 3) == True)
    assert(isintb("+11212", 3) == True)
    assert(isintb("aBCdeF", 16) == True)
    assert(isintb("-aBCdeF", 16) == True)
    assert(isintb("+aBCdeF", 16) == True)
    print("test_isintb() ok")
    
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----

def sumdigits(zahl):
    """Berechnet die Ziffernsumme aus der gegebenen Zahl (int)"""
    sum = 0
    while zahl != 0:
        sum += zahl % 10 # Rest ist immer Einerstelle
        zahl = zahl // 10
    return sum

def test_sumdigits():
    assert(sumdigits(0) == 0)
    assert(sumdigits(1) == 1)
    assert(sumdigits(7) == 7)
    assert(sumdigits(10) == 1)
    assert(sumdigits(11) == 2)
    assert(sumdigits(123) == 6)
    assert(sumdigits(1010) == 2)
    print("test_sumdigits() ok")
    
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def wert_der_ziffer(ziffer):
    """liefert den Wert der Ziffer ziffer (0..9, bzw. A, B, C, ...)"""
    if ord(ziffer) <= ord("9"):
        wert = ord(ziffer) - ord("0")
    else:
        wert = ord(ziffer) - ord("A") + 10
    return wert

def horner(zahl, basis):
    """berechnet Dezimalzahl aus zahl (String) zur Basis basis.
    liefert Zahl. Hornerschema!"""
    dez = 0
    for ziffer in zahl:
        dez *= basis
        dez += wert_der_ziffer(ziffer)
    return dez

def test_horner():
    assert(horner("", 10) == 0)
    assert(horner("1", 10) == 1)
    assert(horner("12", 10) == 12)
    assert(horner("123", 10) == 123)
    assert(horner("1", 2) == 1)
    assert(horner("10", 2) == 2)
    assert(horner("11", 2) == 3)
    assert(horner("4", 16) == 4)
    assert(horner("A", 16) == 10)
    assert(horner("10", 16) == 16)
    print("test_horner() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isipv4(string):
    """Prüft, ob der gegebene String eine IPv4-Adresse enthält.
    IPv4-Adressen sind 4 Zahlen zwischen 0 und 255, die durch einen
    Punkt getrennt sind.
    Beispiele: 127.0.0.1, 193.170.149.129, 81.200.64.185
    Ungültige: 81.2010.64.185, 123.23.12, 127,0,0,1"""
    zahl = ""
    anzpunkte = 0
    anzziffer = 0
    for z in string:
        if '0' <= z <= '9': 
            zahl += z
            anzziffer += 1
        elif z == '.' and anzziffer > 0: # mindestens 1 Ziffer vor Zahl
            if not (0 <= horner(zahl, 10) <= 255):
                return False
            zahl = "" # neu beginnen
            anzziffer = 0
            anzpunkte += 1
        else:
            return False
    if anzpunkte == 3 and anzziffer > 0: # nach 3. Punkt eine Zahl!
        if not (0 <= horner(zahl, 10) <= 255):
            return False
        return True
    else:
        return False

def test_isipv4():
    assert(isipv4("127.0.0.1"))
    assert(isipv4("193.170.149.129"))
    assert(isipv4("81.200.64.185"))
    assert(not isipv4(""))
    assert(not isipv4("81.2010.64.185"))
    assert(not isipv4("123.23.12"))
    assert(not isipv4("123.23.12."))
    assert(not isipv4("123.23.12.3.3"))
    assert(not isipv4("123.23.12.3."))
    assert(not isipv4("127,0,0,1"))
    print("test_isipv4() ok")
    
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def anz_zahlen(string):
    """ermittelt die Anzahl der ganzen Zahlen im String"""
    anzahl = 0
    in_zahl = False
    for zeichen in string:
        if zeichen in "0123456789":
            if not in_zahl:
                anzahl += 1
                in_zahl = True
        else:
            in_zahl = False
    return anzahl

def test_anz_zahlen():
    string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
    assert(4 == anz_zahlen(string))
    assert(0 == anz_zahlen("keine"))
    assert(1 == anz_zahlen("eine Zahl 123"))
    assert(2 == anz_zahlen("zwei 23 und 324"))
    assert(3 == anz_zahlen("drei 23 34 22"))
    assert(4 == anz_zahlen("vier 234 234 234 45"))
    assert(5 == anz_zahlen("5 234 234 234 45"))
    print("test_anz_zahlen() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sum_zahlen(string):
    """ermittelt die Summe der ganzen Zahlen im String. Eine Zahl
    ist eine ununterbrochene Folge von Ziffern.
    Beispiel: sum_zahlen("x 34 3 12k33 44 hallo 23") liefert 149"""
    summe = 0
    zahl = ""
    for zeichen in string:
        if zeichen in "0123456789":
            zahl += zeichen
        else:
            summe += horner(zahl, 10) # umrechnen und dazuzählen
            zahl = "" # neu beginnen
    if len(zahl) > 0: # zuletzt war Zahl, daher dazurechnen
        summe += horner(zahl, 10)
    return summe

def test_sum_zahlen():
    string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
    assert(26460 == sum_zahlen(string))
    assert(0 == sum_zahlen("keine"))
    assert(123 == sum_zahlen("eine Zahl 123"))
    assert(347 == sum_zahlen("zwei 23 und 324"))
    assert(79 == sum_zahlen("drei 23 34 22"))
    assert(747 == sum_zahlen("vier 234 234 234 45"))
    assert(752 == sum_zahlen("5 234 234 234 45"))
    print("test_sum_zahlen() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def iskonto(string):
    """Prüft, ob der String eine gültige Kontonummer enthält. Dabei
    gelten folgende Regeln:
    1. genau 9 Ziffern (es dürfen Leerzeichen dazwischen sein
    2. die letzte Ziffer ist eine Prüfziffer und es gilt
       Die Kontonummer ist genau 9 Stellen lang und ist dann richtig, 
       wenn die folgendermaßen gebildete Summe auf Null endet:
       Ziffern mit ungeradem Index werden addiert(=Teilsumme1);
       Ziffern mit geradem Index werden verdoppelt und das jeweilige 
       Produkt addiert, wenn es einstellig ist, andernfalls wird die
       Quersumme des Produkts addiert(=Teilsumme2);
       Summe= teilsumme1 + Teilsumme2
    Beispiel:
       123456782 1+    3+    5+      7+     2  = 18 Teilsumme1
                   2*2+  4*2+  (1+2)+  (1+6)   = 22 Teilsumme2
                               6*2=12  8*2=16
                                               ------
                                                 40 Summe mod 10= Null
    Beispiele für Kontonummern:
       697199107 richtige Kontonummer
       723016689 richtige Kontonummer
       723016699 falsche Kontonummer
    """
    # entferne alle Leerzeichen (sind ja erlaubt)
    kontonummer = ""
    for c in string:
        if '0' <= c <= '9':
            kontonummer += c
        elif c != ' ':
            return False # nur Ziffern und Leerzeichen erlaubt!
    if len(kontonummer) != 9:
        return False
    
    summe = 0 # alles in einer Summe, aufteilen ist nicht nötig
    for i in range(len(kontonummer)):
        ziffer = ord(kontonummer[i]) - ord('0')
        if (1 + i) % 2 == 1: # ungerade
            summe += ziffer
        else: # gerade
            doppelt = ziffer * 2
            if doppelt >= 10: # Zwei Ziffern
                summe += doppelt % 10 # Einer
                summe += doppelt // 10 # Zehner
            else: # immer noch eine Ziffer
                summe += doppelt
    return summe % 10 == 0 # Summe muss durch 10 teilbar sein

def test_iskonto():
    assert(not iskonto(""))
    assert(not iskonto("a"))
    assert(not iskonto("69719a9107"))
    assert(not iskonto("69719917"))
    assert(not iskonto("723016699"))
    assert(iskonto("723016689"))
    assert(iskonto("697199107"))
    assert(iskonto("123456782"))
    assert(iskonto("12 345 6782"))
    print("test_iskonto() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def reverse_s(string):
    """liefert String in umgekehrter Reihenfolge zurück"""
    s = ""
    for c in string:
        s = c + s
    return s

def test_reverse_s():
    assert("" == reverse_s(""))
    assert("a" == reverse_s("a"))
    assert("ba" == reverse_s("ab"))
    assert("abc" == reverse_s("cba"))
    print("test_reverse() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def toupper(string):
    """liefert String in Großbuchstaben zurück"""
    s = ""
    for c in string:
        if 'a' <= c <= 'z':
            s += chr(ord(c) - ord('a') + ord('A'))
        elif c == 'ä':
            s += 'Ä'
        elif c == 'ö':
            s += 'Ö'
        elif c == 'ü':
            s += 'Ü'
        else:
            s += c
    return s

def test_toupper():
    assert("" == toupper(""))
    assert("A" == toupper("a"))
    assert("AB" == toupper("ab"))
    assert("ÄBC" == toupper("äbc"))
    assert("A" == toupper("a"))
    assert("AB" == toupper("Ab"))
    assert("ÄBC" == toupper("äBc"))
    print("test_toupper() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def tolower(string):
    """liefert String in Kleinbuchstaben zurück"""
    pass
    s = ""
    for c in string:
        if 'A' <= c <= 'Z':
            s += chr(ord(c) - ord('A') + ord('a'))
        elif c == 'Ä':
            s += 'ä'
        elif c == 'Ö':
            s += 'ö'
        elif c == 'Ü':
            s += 'ü'
        else:
            s += c
    return s

def test_tolower():
    assert("" == tolower(""))
    assert("a" == tolower("A"))
    assert("ab" == tolower("AB"))
    assert("äbc" == tolower("ÄBC"))
    assert("a" == tolower("A"))
    assert("ab" == tolower("Ab"))
    assert("äbc" == tolower("äBc"))
    print("test_tolower() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isupper(string):
    """prüft, ob String nur Großbuchstaben enthält"""
    for c in string:
        if 'a' <= c <= 'z' or c in "äöü": # ein Kleinbuchstabe
            return False
    return True

def test_isupper():
    assert(isupper(""))
    assert(isupper("A"))
    assert(isupper("AEÄÖ"))
    assert(not isupper("a"))
    assert(not isupper("abcö"))
    assert(not isupper("AbC"))
    print("test_isupper() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def islower(string):
    """prüft, ob String nur Kleinbuchstaben enthält"""
    for c in string:
        if 'A' <= c <= 'Z' or c in "ÄÖÜ": # ein Großbuchstab
            return False
    return True

def test_islower():
    assert(islower(""))
    assert(islower("a"))
    assert(islower("aeöä"))
    assert(not islower("A"))
    assert(not islower("ABCÖ"))
    assert(not islower("AbC"))
    print("test_islower() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def ispalindrom(string):
    """Prüft, ob der String ein Palindrom ist (von vorne und hinten
    gelesen gleich)."""
    for i in range(len(string)):
        if string[i] != string[-1 - i]:
            return False
    return True

def test_ispalindrom():
    assert(ispalindrom(""))
    assert(ispalindrom("a"))
    assert(ispalindrom("aa"))
    assert(ispalindrom("aba"))
    assert(ispalindrom("abba"))
    assert(not ispalindrom("ab"))
    assert(not ispalindrom("abb"))
    assert(not ispalindrom("abab"))
    print("test_ispalindrom() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def ispalindrom_l(liste):
    """Prüft, ob die Liste von vorne und hinten gelesen gleich ist."""
    return ispalindrom(liste) # sollte äquivalent sein!

def test_ispalindrom_l():
    assert(ispalindrom_l([]))
    assert(ispalindrom_l([1]))
    assert(ispalindrom_l([1, 1]))
    assert(ispalindrom_l([1, 2, 1]))
    assert(ispalindrom_l([1, 2, 2, 1]))
    assert(not ispalindrom_l([1, 2]))
    assert(not ispalindrom_l([1, 2, 2]))
    assert(not ispalindrom_l([1, 2, 1, 2]))
    print("test_ispalindrom_l() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def reverse_l(liste):
    """liefert die Liste in umgekehrter Reihenfolge zurück"""
    l = []
    for e in liste:
        l = [e] + l
    return l

def test_reverse_l():
    assert([] == reverse_l([]))
    assert([1] == reverse_l([1]))
    assert([1, 2] == reverse_l([2, 1]))
    assert([1, 2, 3] == reverse_l([3, 2, 1]))
    print("test_reverse_l() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sum(liste):
    """liefert die Summe aller Zahlen in der Liste"""
    summe = 0
    for e in liste:
        summe += e
    return summe

def test_sum():
    assert(0 == sum([]))
    assert(12 == sum([12]))
    assert(12 == sum([4, 8]))
    assert(12 == sum([4, 4, 4]))
    print("test_sum() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def mittelwert(liste):
    """liefert den Mittelwert (Durchschnitt) aller Zahlen in der Liste"""
    if len(liste) > 0:
        return sum(liste) / len(liste)
    else:
        return 0

def test_mittelwert():
    assert(0 == mittelwert([]))
    assert(1 == mittelwert([1]))
    assert(1.5 == mittelwert([1, 2]))
    assert(2 == mittelwert([2, 2, 2]))
    assert(2 == mittelwert([1, 2, 3]))    
    print("test_mittelwert() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def rmdups(liste):
    """(ReMove DUPlicates) liefert Liste, aus der alle Vielfachen entfernt
    (hintereinander).
    Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 2, 3, 2, 23]
               [99, 99, 23, 99, 99, 12, 2] -> [99, 23, 99, 12, 2]
               [] -> []
               [1, 2, 4, 10] -> [1, 2, 4, 10]"""
    if len(liste) > 0:
        ret = [liste[0]]
        for e in liste:
            if ret[-1] != e: # letztes Element ungleich?
                ret.append(e)
        return ret
    else:
        return liste

def test_rmdups():
    assert([1, 2, 5, 2, 3, 2, 23] == rmdups([1, 2, 2, 2, 5, 2, 3, 2, 2, 23]))
    assert([99, 23, 99, 12, 2] == rmdups([99, 99, 23, 99, 99, 12, 2]))
    assert([] == rmdups([]))
    assert([1, 2, 4, 10] == rmdups([1, 2, 4, 10]))
    print("test_rmdups() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isin(item, liste):
    """ist item in liste enthalten?"""
    for e in liste:
        if item == e:
            return True
    return False

def rmalldups(liste):
    """(ReMove ALL DUPlicates) liefert Liste, aus der alle Vielfachen
    entfernt (müssen nicht hintereinander stehen).
    Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 3, 23]
               [99, 99, 23, 99, 99, 12, 2] -> [99, 23, 12, 2]
               [] -> []
               [1, 2, 4, 10] -> [1, 2, 4, 10]"""
    if len(liste) > 0:
        ret = [liste[0]]
        for e in liste:
#            if e not in ret: # schon vorhanden?
            if not isin(e, ret):
                ret.append(e)
        return ret
    else:
        return liste

def test_rmalldups():
    assert([] == rmalldups([]))
    assert([1, 2, 5, 3, 23] == rmalldups([1, 2, 2, 2, 5, 2, 3, 2, 2, 23]))
    assert([99, 23, 12, 2] == rmalldups([99, 99, 23, 99, 99, 12, 2]))
    assert([1, 2, 4, 10] == rmalldups([1, 2, 4, 10]))
    print("test_rmalldups() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def binsearch(liste, such):
    """liefert den Index von such in der sortierten Liste liste oder -1,
    wenn such in liste nicht vorkommt. Es ist die binäre Suche anzuwenden!
    """
    first = 0
    last = len(liste) - 1
    mid = (last - first) // 2 + first
    #print(first, mid, last)
    while len(liste) > 0 and first <= last:
        if such < liste[mid]:
            last =  mid - 1
        elif such > liste[mid]:
            first = mid + 1
        else:
            return mid #index found
        mid = (last - first) // 2 + first
        #print(first, mid, last)
    return -1 # not found

def test_binsearch():
    """static tests"""
    assert(binsearch([], 1) == -1)
    assert(binsearch([1], 2) == -1)
    assert(binsearch([1], 0) == -1)
    assert(binsearch([1], 1) == 0)
    assert(binsearch([1,3], 0) == -1)
    assert(binsearch([1,3], 2) == -1)
    assert(binsearch([1,3], 1) == 0)
    assert(binsearch([1,3], 3) == 1)
    assert(binsearch([1,3], 4) == -1)
    assert(binsearch([1,3,5], 2) == -1)
    assert(binsearch([1,3,5], 4) == -1)
    assert(binsearch([1,3,5], 1) == 0)
    assert(binsearch([1,3,5], 3) == 1)
    assert(binsearch([1,3,5], 5) == 2)
    assert(binsearch([1,3,5], 6) == -1)
    assert(binsearch([1,3,5,7], 0) == -1)
    assert(binsearch([1,3,5,7], 1) == 0)
    assert(binsearch([1,3,5,7], 3) == 1)
    assert(binsearch([1,3,5,7], 5) == 2)
    assert(binsearch([1,3,5,7], 7) == 3)
    assert(binsearch([1,3,5,7], 9) == -1)
    assert(binsearch([1,3,5,7], 2) == -1)
    assert(binsearch([1,3,5,7], 4) == -1)
    assert(binsearch([1,3,5,7], 6) == -1)
    import random
    for i in range(25):
        liste = [random.randint(0, 100) for i in range(100)]
        liste.sort()
        num = random.randint(0, 100)
        if num in liste:
            if binsearch(liste, num) < 0:
                print(liste)
                print("%d should be found in list" % num)
                assert(binsearch(liste, num) >= 0)
        else:
            if binsearch(liste, num) >= 0:
                print(liste)
                print("%d should not be found in list" % num)
                assert(binsearch(liste, num) < 0)
    print("test_binsearch() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sumteilbar(liste, teiler):
    """Berechnet die Summe aller durch teiler teilbaren Zahlen der Liste"""
    summe = 0
    for e in liste:
        if e % teiler == 0:
            summe += e
    return summe

def test_sumteilbar():
    assert(0 == sumteilbar([], 2))
    assert(0 == sumteilbar([1], 2))
    assert(0 == sumteilbar([1, 3], 2))
    assert(0 == sumteilbar([1, 3, 23], 2))
    assert(2 == sumteilbar([2], 2))
    assert(2 == sumteilbar([1, 2], 2))
    assert(2 == sumteilbar([1, 2, 23], 2))
    assert(32 == sumteilbar([1, 8, 24], 2))
    assert(27 == sumteilbar([3, 8, 24], 3))
    print("test_sumteilbar() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def issorted(liste):
    """Prüft, ob die Liste sortiert ist, d.h. ob e1 <= e2 <= e3 <= ... <= en
    e1, e2, ... en sind die n Elemente der Liste mit Länge n"""
    for i in range(len(liste) - 1):
        if liste[i] > liste[i + 1]:
            return False
    return True

def test_issorted():
    assert(issorted([]))
    assert(issorted([1]))
    assert(issorted([1, 1]))
    assert(issorted([1, 3, 3, 4]))
    assert(not issorted([1, 0]))
    assert(not issorted([1, 2, 1]))
    print("test_issorted() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def printlxl(liste1, liste2):
    """gibt eine Multiplikationstabelle der beiden Listen aus.
    Zum Beispiel:
       a = [1, 2, 4, 5]
       b = [3, 2, 2]
       printlxl(a, b) gibt dann folgendes aus:
         3   2   2 
         6   4   4 
        12   8   8 
        15  10  10 
    Die erste Liste bestimmt die Anzahl der Zeilen, die zweite die Anzahl 
    der Spalten. Es wird immer ein Element der ersten Liste mit einem der
    zweiten Liste multipliziert.
    """
    erg = lxl(liste1, liste2)
    for zeile in erg:
        for spalte in zeile:
            print("%4d" % spalte, end = "")
        print()

def test_printlxl():
    a = [1, 2, 4, 5]
    b = [3, 2, 2]
    printlxl(a, b)
    print("test_printlxl() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def lxl(liste1, liste2):
    """liefert eine Multiplikationstabelle der beiden Listen (Liste von 
    Listen).
    Zum Beispiel:
       a = [1, 2, 4, 5]
       b = [3, 2, 2]
       lxl(a, b) liefert folgende Liste zurück:
       [[3, 2, 2], [6, 4, 4], [12, 8, 8], [15, 10, 10]]
       übersichtlich formatiert:
       [[3, 2, 2], 
        [6, 4, 4], 
        [12, 8, 8], 
        [15, 10, 10]]
    Die erste Liste bestimmt die Anzahl der "Zeilen", die zweite die Anzahl 
    der "Spalten". Es wird immer ein Element der ersten Liste mit einem der
    zweiten Liste multipliziert.
    """
    erg = []
    if len(liste2) > 0:
        for a in liste1:
            zeile = []
            for b in liste2:
                zeile.append(a * b)
            erg.append(zeile)
    return erg

def test_1x1():
    a = [1, 2, 4, 5]
    b = [3, 2, 2]
    assert([[3, 2, 2], [6, 4, 4], [12, 8, 8], [15, 10, 10]] == lxl(a, b))
    assert([] == lxl([], []))
    assert([] == lxl([], [1, 2]))
    assert([] == lxl([1, 2], []))
    print("test_1x1() ok")

#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
# Testaufrufe:
test_isint()
test_isintb()
test_sumdigits()
test_horner()
test_isipv4()
test_anz_zahlen()
test_sum_zahlen()
test_iskonto()
test_reverse_s()
test_toupper()
test_tolower()
test_isupper()
test_islower()
test_ispalindrom()
test_ispalindrom_l()
test_reverse_l()
test_sum()
test_mittelwert()
test_rmdups()
test_rmalldups()
test_binsearch()
test_sumteilbar()
test_issorted()
test_printlxl()
test_1x1()

Die Funktionen isupper() und islower() sind eigentlich nicht korrekt, denn liefert z.B. isupper("A4C") True. Man müsste also eher schreiben:

def isupper(string):
    """prüft, ob String nur Großbuchstaben enthält"""
    for c in string:
        if not ('A' <= c <= 'Z' or c in "ÄÖÜ"):
            return False
    return True

Labels: , ,


Sonntag, 6. März 2011

 

Übungsbeispiele zu Sequenzen, Schleifen und Funktionen in Python (POS1: 1B)

Hier finden Sie eine Reihe von Aufgabenstellungen als Übung zur nächsten praktischen Arbeit.
Gegeben sind minimale Funktionsrümpfe mit der Aufgabenstellung als DocString.

Die Funktionen sind ohne Standardmethoden bzw. Funktionen zu implementieren (ausgenommen die Funktion len()). Sollte es eine Standardfunktion zur Lösung der Aufgabe geben, verwenden Sie diese, um das Ergebnis zu prüfen. Bereiche ([von:bis]) dürfen verwendet werden, sofern sie benötigt werden.

def isint(string)
    """prüft, ob der String eine ganze Zahl ist (Vorzeichen optional, 
    nur Ziffern)"""
    pass

def isintb(string, basis)
    """prüft, ob der String eine ganze Zahl zur Basis basis ist (Vorzeichen
    optional, nur Ziffern)"""
    pass

def isnum(string)
    """prüft, ob der String eine Zahl ist (Vorzeichen optional, Ziffern und
    Komma)"""
    pass

def horner(zahl, basis):
    """berechnet Dezimalzahl aus zahl (String) zur Basis basis.
    liefert Zahl."""
    pass

def sumdigits(zahl):
    """Berechnet die Ziffernsumme aus der gegebenen Zahl (int)"""
    pass

def sumdigits_s(string):
    """Berechnet die Ziffernsumme aus der gegebenen Zahl (str), wenn
    es überhaupt eine Zahl ist. Liefert -1, wenn keine gültige Zahl"""
    pass

def isipv4(string):
    """Prüft, ob der gegebene String eine IPv4-Adresse enthält.
    IPv4-Adressen sind 4 Zahlen zwischen 0 und 255, die durch einen
    Punkt getrennt sind.
    Beispiele: 127.0.0.1, 193.170.149.129, 81.200.64.185
    Ungültige: 81.2010.64.185, 123.23.12, 127,0,0,1"""
    pass

def anz_vokale(string):
    """Zähle die Selbstlaute im String und liefere Anzahl zurück"""
    pass

def anz_zahlen(string):
    """ermittelt die Anzahl der ganzen Zahlen im String. Eine Zahl
    ist eine ununterbrochene Folge von Ziffern.
    Beispiel: anz_zahlen("x 34 3 12k33 44 hallo 23") liefert 6"""
    pass

def sum_zahlen(string):
    """ermittelt die Summe der ganzen Zahlen im String. Eine Zahl
    ist eine ununterbrochene Folge von Ziffern.
    Beispiel: anz_zahlen("x 34 3 12k33 44 hallo 23") liefert 149"""
    pass

def iskonto(string):
    """Prüft, ob der String eine gültige Kontonummer enthält. Dabei
    gelten folgende Regeln:
    1. genau 9 Ziffern (es dürfen Leerzeichen dazwischen sein
    2. die letzte Ziffer ist eine Prüfziffer und es gilt
       Die Kontonummer ist genau 9 Stellen lang und ist dann richtig, 
       wenn die folgendermaßen gebildete Summe auf Null endet:
       Ziffern mit ungeradem Index werden addiert(=Teilsumme1);
       Ziffern mit geradem Index werden verdoppelt und das jeweilige 
       Produkt addiert, wenn es einstellig ist, andernfalls wird die
       Quersumme des Produkts addiert(=Teilsumme2);
       Summe= teilsumme1 + Teilsumme2
    Beispiel:
       123456782 1+    3+    5+      7+     2  = 18 Teilsumme1
                   2*2+  4*2+  (1+2)+  (1+6)   = 22 Teilsumme2
                               6*2=12  8*2=16
                                               ------
                                                 40 Summe mod 10= Null
    Beispiele für Kontonummern:
       697199107 richtige Kontonummer
       723016699 falsche Kontonummer
    """
    pass

def reverse_s(string):
    """liefert String in umgekehrter Reihenfolge zurück"""
    pass

def toupper(string):
    """liefert String in Großbuchstaben zurück"""
    pass

def tolower(string):
    """liefert String in Kleinbuchstaben zurück"""
    pass

def isupper(string):
    """prüft, ob String nur Großbuchstaben enthält"""
    pass

def islower(string):
    """prüft, ob String nur Kleinbuchstaben enthält"""
    pass

def ispalindrom(string):
    """Prüft, ob der String ein Palindrom ist (von vorne und hinten
    gelesen gleich)."""
    pass

def ispalindrom_l(liste):
    """Prüft, ob die Liste von vorne und hinten gelesen gleich ist."""
    pass

def reverse_l(liste):
    """liefert die Liste in umgekehrter Reihenfolge zurück"""
    pass

def sum(liste):
    """liefert die Summe aller Zahlen in der Liste"""
    pass

def mittelwert(liste):
    """liefert den Mittelwert (Durchschnitt) aller Zahlen in der Liste"""
    pass

def rmdups(liste):
    """(ReMove DUPlicates) liefert Liste, aus der alle Vielfachen entfernt
    (hintereinander).
    Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 2, 3, 2, 23]
               [99, 99, 23, 99, 99, 12, 2] -> [99, 23, 99, 12, 2]
               [] -> []
               [1, 2, 4, 10] -> [1, 2, 4, 10]"""
    pass

def rmalldups(liste):
    """(ReMove ALL DUPlicates) liefert Liste, aus der alle Vielfachen
    entfernt (müssen nicht hintereinander stehen).
    Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 3, 23]
               [99, 99, 23, 99, 99, 12, 2] -> [99, 23, 12, 2]
               [] -> []
               [1, 2, 4, 10] -> [1, 2, 4, 10]"""
    pass

def binsearch(liste, such):
    """liefert den Index von such in der sortierten Liste liste oder -1,
    wenn such in liste nicht vorkommt. Es ist die binäre Suche anzuwenden!
    """
    pass

def sumdigits(zahl):
    """Berechnet die Ziffernsumme aus der gegebenen Zahl (int)"""
    pass

def sumteilbar(liste, teiler):
    """Berechnet die Summe aller durch teiler teilbaren Zahlen der Liste"""
    pass

def issorted(liste):
    """Prüft, ob die Liste sortiert ist, d.h. ob e1 <= e2 <= e3 <= ... <= en
    e1, e2, ... en sind die n Elemente der Liste mit Länge n"""
    pass
def printlxl(liste1, liste2):
    """gibt eine Multiplikationstabelle der beiden Listen aus.
    Zum Beispiel:
       a = [1, 2, 4, 5]
       b = [3, 2, 2]
       printlxl(a, b) gibt dann folgendes aus:
         3   2   2 
         6   4   4 
        12   8   8 
        15  10  10 
    Die erste Liste bestimmt die Anzahl der Zeilen, die zweite die Anzahl 
    der Spalten. Es wird immer ein Element der ersten Liste mit einem der
    zweiten Liste multipliziert.
    """
    pass
def lxl(liste1, liste2):
    """liefert eine Multiplikationstabelle der beiden Listen (Liste von 
    Listen).
    Zum Beispiel:
       a = [1, 2, 4, 5]
       b = [3, 2, 2]
       lxl(a, b) liefert folgende Liste zurück:
       [[3, 2, 2], [6, 4, 4], [12, 8, 8], [15, 10, 10]]
       übersichtlich formatiert:
       [[3, 2, 2], 
        [6, 4, 4], 
        [12, 8, 8], 
        [15, 10, 10]]
    Die erste Liste bestimmt die Anzahl der "Zeilen", die zweite die Anzahl 
    der "Spalten". Es wird immer ein Element der ersten Liste mit einem der
    zweiten Liste multipliziert.
    """
    pass

Schreiben Sie zu den Funktionen jeweils passende Testprogramme.

Labels: , ,


Freitag, 14. Januar 2011

 

Ganze Zahlen zählen (Schleife, Sequenzen, Funktionen POS1: 1BHIF)

Schreiben Sie ein Programm anzzahlen.py, welches eine Zeile einliest und in dieser Zeile zähle, wieviele ganze Zahlen vorkommen. Jedes Zeichen, das keine Ziffer ist, gilt als nicht zu einer Zahl gehörend.
Beispiel:
Eingabe:
das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123
Ausgabe:
4 Zahlen gefunden.
Das Programm soll richtige Sätze ausgeben, also "Keine Zahlen gefunden.", wenn in der Eingabe keine Zahlen sind oder "Eine Zahl gefunden.", wenn eine Zahl in der Eingabe war. Ab 4 soll dann die Zahl ausgegeben werden, z.B. "6 Zahlen gefunden."

Mögliche Lösung:
"""
author: Haberstroh, Harald
matnr:  d09666
file:   anzzahlen.py
desc:   Zähle ganze Zahlen
        Beispiel:
            das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123
        Ausgabe:
            4 Zahlen gefunden
date:   14.1.2011
class:  Lehrer
catnr:  33
"""
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----

def anz_zahlen(string):
    """ermittelt die Anzahl der ganzen Zahlen im String"""
    anzahl = 0
    in_zahl = False
    for zeichen in string:
        if zeichen in "0123456789":
            if not in_zahl:
                anzahl += 1
                in_zahl = True
        else:
            in_zahl = False
    return anzahl

def ausgabe(anzahl):
    """gibt deutschen Satz aus mit Anzahl"""
    if anzahl == 0:
        print("Keine Zahl gefunden.")
    elif anzahl == 1:
        print("Eine Zahl gefunden.")
    elif anzahl == 2:
        print("Zwei Zahlen gefunden.")
    elif anzahl == 3:
        print("Drei Zahlen gefunden.")
    else:
        print(anzahl, "Zahlen gefunden.")
        
def main():
    """EVA Eingave Verarbeitung Ausgabe - das Hauptprogramm"""
    string = input("> ")
    anzahl = anz_zahlen(string)
    ausgabe(anzahl)

def test():
    """Testen von anz_zahlen() und ausgabe()"""
    string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
    anzahl = anz_zahlen(string)
    ausgabe(anzahl)
    ausgabe(anz_zahlen("keine"))
    ausgabe(anz_zahlen("eine Zahl 123"))
    ausgabe(anz_zahlen("zwei 23 und 324"))
    ausgabe(anz_zahlen("drei 23 34 22"))
    ausgabe(anz_zahlen("vier 234 234 234 45"))
    ausgabe(anz_zahlen("5 234 234 234 45"))

    
if __name__ == '__main__':
    main()
#    test()
Beachten Sie, dass ich hier eine eigene Funktion test() gemacht habe, um viele Testfälle immer wieder leicht probieren zu können. Statt main() muss dann nur test() aufgerufen werden.
Das Programm wäre auch ohne die Funktion test() fertig und korrekt. test() half nur bei der Entwicklung bei der Fehlersuche.

Labels: , , ,


Freitag, 3. Dezember 2010

 

Wurzelberechnung (POS1: 1BHIF)

Man kann die Wurzel einer Zahl berechnen mit folgender Formel

xn = (xn-1 + a / xn-1) / 2

Man beginnt damit, dass a und x0 gleich der Zahl, aus der man die Wurzel ziehen will, setzt und x1 berechnet. Dann berechnet man x2 usw. bis sich die beiden letzten Werte nur mehr gering unterscheiden (z.B. die Differenz kleiner 0,0000001 ist).

Schreiben Sie eine Funktion wurzel(zahl, genauigkeit), welche nach obiger Methode die Wurzel berechnet.

Erstellen Sie ein Programm wurzel.py, welche eine Tabelle der Wurzeln der Zahlen 1 bis 20 bei den Genauigkeiten 0.01, 0.0001 sowie 0.0000001 ausgibt:
 1:  1.0000000  1.0000000  1.0000000
 2:  1.4142157  1.4142136  1.4142136
 3:  1.7320508  1.7320508  1.7320508
 4:  2.0000001  2.0000000  2.0000000
 5:  2.2360689  2.2360680  2.2360680
 6:  2.4494944  2.4494897  2.4494897
 7:  2.6457670  2.6457513  2.6457513
 8:  2.8284271  2.8284271  2.8284271
 9:  3.0000000  3.0000000  3.0000000
10:  3.1622777  3.1622777  3.1622777
11:  3.3166248  3.3166248  3.3166248
12:  3.4641017  3.4641016  3.4641016
13:  3.6055514  3.6055513  3.6055513
14:  3.7416576  3.7416574  3.7416574
15:  3.8729837  3.8729833  3.8729833
16:  4.0000006  4.0000000  4.0000000
17:  4.1231067  4.1231056  4.1231056
18:  4.2426425  4.2426407  4.2426407
19:  4.3589018  4.3588989  4.3588989
20:  4.4721402  4.4721360  4.4721360

Labels: , ,


 

Musterlösung zu Übungsbeispiele für Python vom 1.12.2010 (POS1: 1BHIF)

Prüfen, ob durch die Angabe dreier Längen ein Dreieck gegeben ist.
Zwei Seiten müssen immer länger als die dritte sein. Man muss dies für alle Möglichkeiten prüfen, denn z.B.
a = 3, b = 4, c = 1
Da stimmt zwar a + b > c (7 > 1) und b + c > a (4 > 3), jedoch nicht a + c > b (4 == 4)!
Bei der Lösung wird eine Schleife verwendet.
def ist_dreieck(a, b, c):
    """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
    ist"""
    i = 3
    while i > 0:
        if a + b <= c:
            return False # kein Dreieck
        a, b, c = b, c, a
        i = i - 1
    return True
Man könnte das Problem natürlich auch durch logische Verknüpfung der Prüfungen lösen:
def ist_dreieck(a, b, c):
    """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
    ist"""
    if a + b > c and b + c > a and c + a > b:
        ret = True
    else:
        ret = False
    return ret
Oder gleich so:
def ist_dreieck(a, b, c):
    """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
    ist"""
    return a + b > c and b + c > a and c + a > b
Bei der zweiten Aufgabe soll geprüft werden, ob durch zwei Seiten und einem Winkel ein Quadrat gegeben ist. Die beiden Seiten müssen gleich lang sein (und größer 0) und der Winkel 90°:
def ist_quadrat(a, b, w):
    """liefert True, wenn durch a und b sowie dem Winkel w ein 
    Quadrat definiert ist"""
    quadrat = False
    if a > 0:
        if a == b:
            if w == 90:
                quadrat = True
    # else entfällt, da die Variable quadrat schon mit False vorbelegt ist.
    return quadrat
Oder wieder kürzer mit logischer Verknüpfung:
def ist_quadrat(a, b, w):
    """liefert True, wenn durch a und b sowie dem Winkel w ein 
    Quadrat definiert ist"""
    return a == b and w == 90 and a > 0
Die Schaltjahrprüfung könnte so erfolgen:
def ist_schaltjahr(jahr):
    """liefert True, wenn das gegebene Jahr ein Schaltjahr ist.
    Seit Ende 1582 gilt der Gregorianische Kalender, bei dem folgende Regel
    für die Schaltjahrbestimmung anzuwenden sind:
        In allen Jahren, deren Jahreszahl durch vier teilbar ist, ist der 
        29. Februar ein Schalttag und damit ist dieses Jahr ein Schaltjahr.
        Eine Ausnahme bilden allerdings die vollen Jahrhundertjahre 1700, 
        1800, 1900 usw., auch Säkularjahre genannt. Hiervon erhalten nur 
        diejenigen einen Schalttag, deren Jahreszahl durch 400 teilbar ist. 
        Jedes vierte Säkularjahr ist somit ein Schaltjahr.
    Für alle Jahre <= 1582 liefert die Funktion False, weil da das
    Schaltjahr nicht definiert ist, sonst gilt obige Regel."""
    if jahr <= 1582:
        schaltjahr = False
    elif jahr % 400 == 0:
        schaltjahr = True
    elif jahr % 100 == 0:
        schaltjahr = False
    elif jahr % 4 == 0:
        schaltjahr = True
    else:
        schaltjahr = False
    return schaltjahr
Jahre bis 1582 können keine Schaltjahre sein, da der Gregorianische Kalender erst im Jahr 1582 definiert wurde. Zum Test der Schaltjahrprüfung noch ein paar Worte, aber zunächst die Testfunktion, die ein paar Jahreszahlen prüft, von denen man weiß, dass sie kein Schaltjahr sind sowie Zahlen, bei denen bekannt ist, dass sie Schaltjahre sind:
def test_ist_schaltjahr():
    for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003):
        assert not ist_schaltjahr(jahr)
    for jahr in (1996, 2000, 2004):
        assert ist_schaltjahr(jahr)
    print("ist_schaltjahr ok")
Die Anweisung assert ist für Programmierer und dient zum Prüfen der Bedingung, die gleich dahinter folgt, gedacht. Zum Beispiel:
assert 3 < 4
Die Bedingung ist wahr, daher läuft das Programm weiter. Ist die Bedingung hingegen falsch, so wird das Programm mit einer Fehlermeldung abgebrochen:
>>> assert 3 > 4
Traceback (most recent call last):
  File "", line 1, in 
    assert 3 > 4
AssertionError
Zusätzlich kann ein Text als Fehlermeldung angegeben werden:
>>> assert 3 > 4, "3 ist nicht größer als 4"
Traceback (most recent call last):
  File "", line 1, in 
    assert 3 > 4, "3 ist nicht größer als 4"
AssertionError: 3 ist nicht größer als 4
Angewendet auf obige Testfunktion bedeutet das, dass immer, wenn assert not ist_schaltjahr(jahr) die Funktion ist_schaltjahr(jahr) den Wert False leifern muss und wenn assert ist_schaltjahr(jahr) steht, True geleifert werden muss, damit das Programm nicht abgebrochen wird. Der nächste Punkt ist die for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003):-Zeile. Die Variable jahr bekommt der Reihe nach die Werte 1000, 1580, 1581, 1582, 1900, 1999, 2003 und der eingerückte Code-Block (die eine Zeile) wird ausgeführt. Das ist die for-Schleife, welche im Buch im Kapitel 7 auch erklärt wird. Die Funktion test_ist_schaltjahr() prüft also zunächst ein paar Jahre, die kein Schaltjahr sind und ein paar Schaltjahre. Die Fibonaccizahlen können wie folgt ermittelt werden:
def fib(n):
    """liefert die Fibonaccizahl zu n. Die Zahlen sind wie definiert:
        fib(0) -> 0
        fib(1) -> 1
        fib(2) -> 1
        fib(3) -> 2
        fib(4) -> 3
        fib(5) -> 5
        fib(6) -> 8
        ...
        fib(10) -> 55
        ...
        fib(15) -> 610"""
    f = 0
    a = 0
    b = 1
    i = 0
    while i < n:
        f = a + b
        b, a = a, f
        i += 1
    return f
Für n = 0 und n = 1 sind die (Anfangs-)Werte vordefiniert. fib(0) = 0 und fib(1) = 1. Danach gilt die Regel, dass die n. Fibonaccizahl die Summe der beiden Vorgänger ist, also fib(n - 1) + fib(n - 2) (Siehe dazu auch Wikipedia: Fibonacci-Folge). Die Variable f hat immer den Wert der aktuellen Fibonaccizahl und ist daher mit 0 initialisiert. Die Variable a und b haben immer den Wert der beiden Vorgänger. Sie können das leicht sehen, wenn Sie print(...)-Anweisungen einfügen und sich dadurch den Ablauf der Berechnung anzeigen lassen:
def fib(n):
    """liefert die Fibonaccizahl zu n."""
    f = 0
    a = 0
    b = 1
    i = 0
    while i < n:
        f = a + b
        print(i, ":  f =", f, "a =", a, "b =", b) # Testausgabe
        b, a = a, f
        i += 1
    return f

print(fib(10))
..gibt dann folgendes aus:
0 :  f = 1 a = 0 b = 1
1 :  f = 1 a = 1 b = 0
2 :  f = 2 a = 1 b = 1
3 :  f = 3 a = 2 b = 1
4 :  f = 5 a = 3 b = 2
5 :  f = 8 a = 5 b = 3
6 :  f = 13 a = 8 b = 5
7 :  f = 21 a = 13 b = 8
8 :  f = 34 a = 21 b = 13
9 :  f = 55 a = 34 b = 21
55
Die Ausgabe einer Tabelle mithilfe der Funktion fib() ist einfach (oder doch etwas kompliziert, weil die eckigen Klammern dazukommen):
def fibtab(n):
    """erzeugt eine Tabelle der Fibonaccizahlen bis inclusive n.
    z.B. gibt fibtab(10) folgendes aus:
        [0, 1, 1, 2, 3, 5, 8]
    oder fibtab(100):
        [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    Hinweis:
        verwenden Sie als Zeilenumbruch ", " beim print, also
            print(wert, end=', ')
        außer natürlich beim letzten Wert, hier ist "]" gefordert.
    """
    i = 0
    print("[", end = "")
    f = fib(i)
    while f <= n:
        print(f, end = "")
        i += 1
        f = fib(i)
        if f > n:
            print("]")
        else:
            print(", ", end = "")
Wir müssen sicherstellen, dass zunächst "[" ohne Zeilenumbruch ausgegeben wird. Die Funktion print(...) hat einen optionalen Parameter end, der angibt, was zum Schluss ausgegeben werden soll. Standardmäßig ist das "\n", was einen Zeilenumbruch bewirkt. Setzt man den Wert end = "", so wird ein Leerstring, also nichts, ausgegeben. In der Schleife muss man noch prüfen, ob man das Ende erreicht hat und in diesem Fall "]" (mit Zeilenumbruch) ausgibt. Im Normalfall wird ein Komma ohne Zeilenumbruch ausgegeben (letzte Zeile). Beachten Sie, dass der Parameter n hier die Grenze der Fibonaccizahl angibt und nicht die wievielte (wie bei fib(n)). Die Lösung zum Beispiel, die Summe der Vielfachen von 3 und 5 kleiner als ein Maximum:
def sum_3_5(max):
    """
    bilde Summe der Vielfachen von 3 und 5 kleiner als max.
    Beispielsweise liefert sum_3_5(10) 23, weil
        die Vielfachen von 3 < 10 sind
            3 + 6 + 9 = 18
        die Vielfachen von 5 < 10 sind
            5
        18 + 5 = 23
    sum_3_5(20) liefert 78, weil
        3+  6+9+   12+15+18=63
          5+    10+        =15 (15 ist in obiger Liste schon enthalten!)
    sum_3_5(25) liefert 143, weil
        3+  6+9+   12+   18+   21+24=93 (Vielfache von 5 stehen darunter)
          5+    10+   15+   20      =50
    sum_3_5(100) liefert 2318 (ohne Beweis)
    """
    summe = 0
    i = 0
    while i < max:
        if i % 5 == 0:
            summe += i
        elif i % 3 == 0:
            summe += i
        i += 1
    return summe
Die Laufvariable i wird immer dann zur summe dazugezählt, wenn sie durch 5 teilbar ist oder wenn sie durch 3 teilbar ist. Der Operator % berechnet den Rest der Division. Ist der Rest 0, so ist die erste durch die zweite Zahl teilbar. Das Beispiel zum finden des nächstkleineren bzw. gleichen Quadrats kann so mit einer Probiermethode gelöst werden:
def minquad(zahl):
    """finde die nächstkleinere oder gleichgroße ganze Zahl, die eine 
    Quadratzahl ist. Beispiele:
        minquad(16) -> 16 (weil 4 * 4 = 16 <= 16)
        minquad(24) -> 24 (weil 4 * 4 = 16 <= 14)
        minquad(25) -> 25 (weil 5 * 5 = 25 <= 25)
        minquad(26) -> 25 (weil 5 * 5 = 25 <= 26)
    """
    i = 0
    mq = 0
    while i ** 2 <= zahl:
        mq = i ** 2
        i += 1
    return mq
i ** 2 bedeutet i2. Man könnte natürlich auch i * i schreiben. Diese Funktion prüft einfach sukzessive alle Quadrate, bis eines gefunden wurde, das größer als die gegebene Zahl ist. Der Wert davor (die Variable mq) ist natürlich das Ergebnis, weil das der größte Wert war, für den die Bedingung gilt. Es geht natürlich schneller und einfacher, wenn man sich eine Formel überlegt:
from math import sqrt
from math import floor
def minquad(zahl):
    """finde die nächstkleinere oder gleichgroße ganze Zahl, die eine 
    Quadratzahl ist. Beispiele:
        minquad(16) -> 16 (weil 4 * 4 = 16 <= 16)
        minquad(24) -> 16 (weil 4 * 4 = 16 <= 24)
        minquad(25) -> 25 (weil 5 * 5 = 25 <= 25)
        minquad(26) -> 25 (weil 5 * 5 = 25 <= 26)
    """
    return int(floor(sqrt(zahl))) ** 2
Die Funktion floor(x) liefert die nächstkleinere ganze Zahl zu x (bei positiven Zahlen schneidet dir Funktion die Nachkommastellen der übergebenen Zahl ab). Z.B:
>>> from math import floor
>>> floor(3.14)
3
>>> floor(3)
3
>>> floor(-3.14)
-4
Wenn man die nächstkleinere ganze Zahl der Wurzel quadriert, hat man das gewünschte Ergebnis. Die Turtle-Funktion zum Dreieckzeichnen könnte wie folgt aussehen und braucht nicht weiter erklärt werden:
def dreieck(a, w):
    """zeichnet ein gleichseitiges Dreieck der Seitenlänge a, gedreht um
    den Winkel w. w = 0 bedeutet, dass die eine Seite horizional ist. w = 90
    bedeutet, dass das Dreieck nach LINKS um 90° gedreht ist, d.h. eine Seite
    ist vertikal.
    Das Dreieck soll rechts neben des angegebenen Punktes gezeichnet werden.
    """
    # nehme an Turtle sieht nach oben (wie auch beim Starten)
    right(90 - w)
    pendown()
    for i in range(3):
        forward(a)
        left(120)
    penup()
    left(90 - w)
Um ein Dreieck an eine bestimmte Position zu setzen, kann zusätzlich die Funktion setpos(x, y), welche die Turtle an die Postion x,y setzt, verwendet werden:
def dreieck_an_pos(a, w, x, y):
    """zeichnet ein Dreieck mit Hilfe der Funktion dreieck(a, w) an der 
    Position x, y."""
    penup()
    setpos(x, y)
    dreieck(a, w)
Abgesehen von den Turtle-Funktionen können Sie die Funktionen direkt auf der Website http://codepad.org testen. Dort können Sie auch andere Programmiersprachen probieren. Die Python-Version ist leider nicht aktuell, daher könnte es sein, dass einiges doch nicht direkt so funktioniert. Diese einfachen Beispiele funktionieren aber.
Hier ist zu minquad(zahl) zu sehen:

Labels: , ,


Mittwoch, 1. Dezember 2010

 

Übungsbeispiele für Python (POS1: 1BHIF)

Vervollständigen Sie die folgenden Funktionsdefinitionen und schreiben Sie passende Testaufrufe.

def ist_dreieck(a, b, c):
    """liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
    ist"""
    return True

def ist_quadrat(a, b, w):
    """liefert True, wenn durch a und b sowie dem Winkel w ein 
    Quadrat definiert ist"""
    return True

def ist_schaltjahr(jahr):
    """liefert True, wenn das gegebene Jahr ein Schaltjahr ist.
    Seit Ende 1582 gilt der Gregorianische Kalender, bei dem folgende 
    Regel für die Schaltjahrbestimmung anzuwenden sind:
        In allen Jahren, deren Jahreszahl durch vier teilbar ist, ist
        der 29. Februar ein Schalttag und damit ist dieses Jahr ein 
        Schaltjahr.
        Eine Ausnahme bilden allerdings die vollen Jahrhundertjahre 1700, 
        1800, 1900 usw., auch Säkularjahre genannt. Hiervon erhalten nur 
        diejenigen einen Schalttag, deren Jahreszahl durch 400 teilbar
        ist. Jedes vierte Säkularjahr ist somit ein Schaltjahr.
    Für alle Jahre <= 1582 liefert die Funktion False, weil da das
    Schaltjahr nicht definiert ist, sonst gilt obige Regel."""
    return False

def fib(n):
    """liefert die Fibonaccizahl zu n. Die Zahlen sind wie definiert:
        fib(0) -> 0
        fib(1) -> 1
        fib(2) -> 1
        fib(3) -> 2
        fib(4) -> 3
        fib(5) -> 5
        fib(6) -> 8
        ...
        fib(10) -> 55
        ...
        fib(15) -> 610"""
    return 1

def fibtab(n):
    """erzeugt eine Tabelle der Fibonaccizahlen bis inclusive n.
    z.B. gibt fibtab(10) folgendes aus:
        [0, 1, 1, 2, 3, 5, 8]
    oder fibtab(100):
        [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    Hinweis:
        verwenden Sie als Zeilenumbruch ", " beim print, also
            print(wert, end=', ')
        außer natürlich beim letzten Wert, hier ist "]" gefordert.
    """
    print("[0, 1, 1, 2, 3, 5, 8]")

def sum_3_5(max):
    """
    bilde Summe der Vielfachen von 3 und 5 kleiner als max.
    Beispielsweise liefert sum_3_5(10) 23, weil
        die Vielfachen von 3 < 10 sind
            3 + 6 + 9 = 18
        die Vielfachen von 5 < 10 sind
            5
        18 + 5 = 23
    sum_3_5(20) liefert 78, weil
        3+  6+9+   12+15+18=63
          5+    10+        =15 (15 ist in obiger Liste schon enthalten!)
    sum_3_5(25) liefert 143, weil
        3+  6+9+   12+   18+   21+24=93 (Vielfache von 5 stehen darunter)
          5+    10+   15+   20+     =50
    sum_3_5(100) liefert 2318 (ohne Beweis)
    """
    return 23

def minquad(zahl):
    """finde die nächstkleinere oder gleichgroße ganze Zahl, die eine 
    Quadratzahl ist. Beispiele:
        minquad(16) -> 16 (weil 4 * 4 = 16 <= 16)
        minquad(24) -> 16 (weil 4 * 4 = 16 <= 24)
        minquad(25) -> 25 (weil 5 * 5 = 25 <= 25)
        minquad(26) -> 25 (weil 5 * 5 = 25 <= 26)
    """
    return zahl

def dreieck(a, w):
    """zeichnet ein gleichseitiges Dreieck der Seitenlänge a, gedreht um
    den Winkel w. w = 0 bedeutet, dass die eine Seite horizional ist. 
    w = 90 bedeutet, dass das Dreieck nach LINKS um 90° gedreht ist, d.h.
    eine Seite ist vertikal.
    Das Dreieck soll rechts neben des angegebenen Punktes gezeichnet
    werden.
    """
    pass

def dreieck_an_pos(a, w, x, y):
    """zeichnet ein Dreieck mit Hilfe der Funktion dreieck(a, w) an der 
    Position x, y."""
    pass
Hier folgt ein Beispielaufruf für die Schaltjahrfunktion:
def test_ist_schaltjahr():
    for jahr in (1000, 1581, 1582, 1900, 1999, 2003):
        assert not ist_schaltjahr(jahr)
    for jahr in (1996, 2000, 2004):
        assert ist_schaltjahr(jahr)
    print("ist_schaltjahr ok")
Sollte ist_schaltjahr() richtig implementiert sein, dann müsste "ist_schaltjahr ok" ausgegeben werden. Andernfalls wird das Programm bei einer der assert-Anweisungen abgebrochen werden. assert verwendet man als Programmierer um Bedingungen zu prüfen, die, falls sie nicht erfüllt sind, auf einen Programmierfehler hinweisen. Als Bedingung kann alles rechts neben dem assert stehen, das True ("alles ok") oder False liefert. Die Testaufrufe für alle Funktionen sollten dann etwa so zusammengefasst werden:
def main():
    """Hauptprogamm zum Testen aller Funktionen"""
    test_ist_dreieck()
    test_ist_quadrat()
    test_ist_schaltjahr()
    test_fib()
    test_sum_3_5()
    test_minquad()
    test_dreieck()
    test_dreieck_an_pos()
Dieses main() muss natürlich auch erst aufgerufen werden (keine Einrückung):
main()
Wenn Sie das Programm laufen lassen, dann sieht sie Ausgabe, wenn alles funktioniert (sinngemäß) so aus:
ist_dreieck ok
ist_quadrat ok
ist_schaltjahr ok
fib ok
sum_3_5 ok
minquad ok
Die Funktionen test_dreieck() sowie test_dreieck_an_pos() bewirken eine Zeichnung der folgenden Art (je nach Aufrufe):
Hier waren es die Aufrufe:
def test_dreieck():
    reset()
    dreieck(60, 0)
    dreieck(60, 90)
    dreieck(60, -60)

def test_dreieck_an_pos():
    dreieck_an_pos(70, 0, 50, 50)
    dreieck_an_pos(70, 180, -50, -50)
Es ist also "optische Kontrolle" nötig.

Labels: , ,


Donnerstag, 11. November 2010

 

Code-Kata

Beim Karate (z.B. Karatedo Doshinkan) gibt es Kata (dt. "Form", siehe auch Kata auf Wikipedia), eine spezielle Übungsform, bei der man als Training gegen einen oder mehrere (vorgestellte) Gegner kämpft. Dabei ist der Bewegungsablauf aber stilisiert und fix vorgegeben. Das oftmalige Wiederholen der Bewegungsabläufe in Form von Kata ist unerlässlich für den persönlichen Fortschritt. Denn nur Übung macht den Meister.

Auch Programmieren beherrscht man nur durch ständiges Training. Nur durch Üben wird man auch hier zum Meister. Aber nicht nur durch den Kampf (Programmieren für das Geschäft) sondern auch durch Katas. Diese Idee für's Programmieren hat Dave Thomas von den Pragmatischen Programmieren (meines Wissens) erstmalig aufgegriffen und publiziert: Code Kata

Sehr empfehlenswert für alle, die Programmieren meistern wollen.

Die Idee der Code Kata fasziniert und berührt mich besonders, da ich selber jahrelang trainiert habe.

Labels: , , , , , , ,


Freitag, 15. Oktober 2010

 

Listings (Source-Code drucken)

Sollten Sie Source Code in gedruckter Form abliefern (müssen), dann sollte ein Listing etwa so aussehen:
Das Listing sollte folgende Eigenschaften aufweisen:
Beispiel mit Zeilennummern:

Beispiel mit Zeilennummern, nur jede 5. Zeile bekommt eine Nummer:

Unter Linux können Sie den Befehl a2ps (ASCII to PostScript, 2 = two = to, daher a2ps) verwenden.

Beispiele:
a2ps -Phpg1 dreieck.py
Die Datei dreieck.py wird auf dem Drucker hpg1 ohne Zeilennummern gedruckt.

a2ps --line-numbers=1 -Phpg2 dreieck.py newprog.py
Die Dateien dreieck.py und newprog.py werden am Drucker hpg2 mit Zeilennummern gedruckt.

a2ps --line-numbers=5 -Phpg3 dreieck.py newprog.py
Die Dateien dreieck.py und newprog.py werden am Drucker hpg3 mit Zeilennummern gedruckt, wobei nur jede fünfte Zeilennummer gedruckt wird.

Weitere Optionen zu a2ps finden Sie in der man-Page (man a2ps).

Die meisten IDEs (z.B. eclipse oder netbeans) und viele Editoren bieten ähnliche Möglichkeiten, jedoch passt bei a2ps der Ausdruck praktisch immer (abgesehen davon, dass a2ps nur ASCII-versteht und damit Probleme mit Umlauten hat, aber damit kann man leben).

Labels: , , ,


Mittwoch, 6. Oktober 2010

 

Header für Python-Programme (POS1: 1BHIF, 2AHIF, 2CHIF)

Jedes Python-Programm bzw. Python-Modul muss einen Header der Form
"""
author: AUTOR
matnr:  EVIDENZNUMMER
file:   DATEINAME
desc:   ZWECK
date:   DATUM
class:  KLASSE
catnr:  KATALOGNUMMER
"""
besitzen. Zum Beispiel:
"""
author: Neubauer, Claudia
matnr:  d09666
file:   fibonacci.py
desc:   Gibt die Fibonacci-Zahlen bis zu einer gegebenen Grenze aus
date:   2010-10-06
class:  2AHIF
catnr:  33
"""

Labels: , ,


This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]