Anmerkungen zu den Aufgaben bzw. Lösungen

1. Allgemeine Hinweise

  1. DocStrings statt Kommentaren im Kopf von Modulen, Funktionen, Klassen und Methoden (und nur dort!):

    def factorial(n):
        """function without recursion"""
        if n > 0:
            ...
    
  2. Bei Bedingungen: keine Klammern erforderlich, ggf. True und False verwenden:

    while True:
        ...
    
    # nicht: while(1):
    
  3. Styleguide (Lesbarkeit): Keyword Arguments ohne, Zuweisungen mit Leerzeichen; vor und nach Operatoren Leerzeichen:

    def __init__(self, anrede="", ...):
        self.anrede = anrede
    
    result = wert1 * wert2
    
  4. Innerhalb von Klammern ist bei mehrzeiligen Ausdrücken kein "continuation character" () am Zeilenende erforderlich:

    person = AdressLabel(anrede="Herr", titel="Dr.", vorname="Hans",
               nachname="Mueller", strasse="Holzweg", hausnummer=6,
               plz= 12345, ort="Dorf")
    
  5. Namen mit Doppel-Unterstrich sind per Konvention für Python-interne Zwecke reserviert:

    # nicht: def __checkValue__(value):  sondern einfach:
    
    def checkValue(value):
        ...
    
  6. Der Aufbau langer Strings durch Konkatenierung (+ Operator) ist ineffizient, da bei jeder Operation ein neues String Objekt erzeugt und der Inhalt des bisherigen String kopiert wird; bessere Lösung: Ablegen der Teilstrings (Felder, Zeilen) in einer Liste, am Schluss per join() zusammenfügen, etwa:

    lines = []
    fields = []
    if self.address:
        fields.append(self.address)
    if self.title:
        fields.append(self.title)
    ...
    lines.append(' '.join(fields))
    ...
    return '\n'.join(lines)
    
  • Noch einfacher lassen sich solche Strings per list comprehension aufbauen:

    lines.append(' '.join([f for f in (self.address, self.title, ...)
                             if f]))
    ...
    return '\n'.join(lines)
    
  1. Interne Methoden ("__xxx__") nicht unmittelbar aufrufen sondern die entsprechenden eingebauten Funktionen verwenden:

    self.firma = str(firma)  # nicht: firma.__str__()
    # ist hier aber eigentlich auch überflüssig...
    
    if len(self.args) != 0:  # nicht: self.args.__len__
    # oder noch einfacher:
    if self.args:
    
    if 'url' in self.args:   # nicht: self.args.__contains__('url')
    
  2. Styleguide: Groß-/Kleinschreibung beachten:

    self.anrede             # nicht: self.Anrede
    class Label(object):    # nicht: class label(object):
    def drive(self):        # nicth: def Drive(self):
    
  3. Sprechende Namen verwenden:

    label = Label(anrede, name, ...)  # (statt: Label(an, na, ...)
    
  4. Niemals from xxxx import * verwenden - das macht den Namensraum unkontrollierbar und führt dazu, dass nicht mehr nachvollzogen werden kann, woher welche Funktionen kommen.

  5. Umwandlung von Zeit-Strings in Sekunden, dadurch einfacher Vergleich von Zeitwerten; mit strptime lassen sich auch Datumseingaben parsen:

    from time import time, mktime, strptime
    if time() >= mktime(strptime(<Zeit-String>, <Format>)):
        ...
    
  6. Veränderliche Objekte nicht auf Klassen-Ebene definieren, da sie sonst allen instances der Klasse gemeinsam sind:

    class Scheduler(object):
    
    # nicht: commands = []
    
    def __init__(self, filename):
        self.filename
        self.commands = []
    
  7. Styleguide: Package- und Modulnamen immer durchgängig in Kleinbuchstaben, ohne Sonderzeichen (z.B. Unterstriche); so wird sichergestellt, dass es keine unerwarteten Probleme auf unterschiedlichen Betriebssystemen gibt.

  8. Dynamische Zuordnung von Funktionen (Kommandos) zu Strings: am einfachsten über ein Dictionary:

    from operator import add, sub, mul, div
    operators = {'+': add, '-': sub, '*': mul, '/': div}
    op = operators.get(operator)
    if op is None:
        result = 'invalid operator'
    else:
        result = op(a, b)
    
  9. Fehlertolerante Dictionary-Abfrage (statt try:/except:):

    if key in dictionary:  # has_key() ist veraltet
        ...
    # oder:
    value = dictionary.get(key, None) # oder anderer default statt None
    
  10. Anführungszeichen z.B. für die Generierung von HTML- oder XML-Tags können ohne Backslash eingegeben werden, wenn der String in die alternativen Anführungszeichen eingeschlossen wird:

    line = '<input name="operand1" type="text" size="9" />'
    
  11. Schleifen nicht über range(len(x)) laufen lassen, sondern die Liste unmittelbar verwenden, ggf. unter Nutzung der enumerate() Funktion; auch für den Index-Zugriff in Listen ist len(x) nicht erforderlich:

    lastweek = current_month[-1]
    for j, d in enumerate(lastweek):
        if d == 0:
            current_month[-1][j] = firstweekafter[j]
    
  12. Styleguide: Attribut- und Methoden-Namen mit Doppel-Unterstrich am Anfang sollten nur verwendet werden, wenn aus technischen Gründen zwingend erforderlich, standardmäßig also:

    class Address(object):
    
        anrede = ''
        # nicht: __anrede
    
  13. String-Operationen: Für String-Operationen nicht das veraltete string Modul verwenden, sondern String-Methoden:

    '\n'.join(lines)    # nicht: string.join(lines, '\n')
    
  14. for statt while: Schleifen mit for und range() sind meist die bessere (kürzere und schnellere) Lösung, z.B.:

    result = 1
    for x in range(1, n + 1):
        result *= x
    

2. Hinweise zu einzelnen Aufgaben

2.1 Adress-Label

  1. Die Methode format() soll einen String zurückgeben, keine Ausgabe über print!

  2. Überflüssige Leerzeichen sollen auch eliminiert werden, wenn ein Teilstring leer ist; dies ist bei folgendem Beispiel bei fehlendem Vornamen nicht der Fall:

    zeile2 = (self.titel + " " + self.vorname + " " + self.nachname).strip()
    
  3. Beispiel für Ergebnis - Adress-Label auf einem Brief:

    Herrn Prof. Dr. Alfons Zweistein
    Musterstraße 17
    
    47118 Musterstadt
    
    --- oder ---
    
    Frau Meier
    
    81489 Musterdorf
    

2.2 Verkehrs-Simulation

  1. Position und Geschwindigkeit sollen Attribute der Klasse Car sein, nicht in World der in globalen Variablen abgelegt werden. Analog sollten die Fahrzeuge in einem Attribute (self.cars) des World Objekts abgelegt werden. Die Methode drive() benötigt dann keine Parameter.

Calendar

« May 2012 »
  Mo Tu We Th Fr Sa Su
18 1 2 3 4 5 6
19 7 8 9 10 11 12 13
20 14 15 16 17 18 19 20
21 21 22 23 24 25 26 27
22 28 29 30 31