Errata zum Grundkurs »Python« (2018)

Diese Seite enthält Updates und Errata zum Buch »Python — Der Grundkurs«.

S. 34 (Hello World)

Wenn Sie unter macOS den Editor TextEdit verwenden, müssen Sie vor dem erstmaligen Speichern Format/In reinen Text umwandeln ausführen.

S. 43 (Thonny)

Wenn Sie Thonny auch für fortgeschrittene Beispiele einsetzen, stolpern Sie über kurz oder lang über den Fehler module not found. Das liegt daran, dass Thonny eine eigene Python-Version samt Modulen verwaltet. Sie müssen das fehlende Modul daher innerhalb von Thonny installieren. Wie das geht, habe ich hier beschrieben:

https://kofler.info/modulverwaltung-in-thonny

S. 63 (Gültigkeitsbereich von Variablen)

Um die Gültigkeitsregeln von Python mit anderen Sprachen zu vergleichen, habe ich am Beginn der Seite ein winziges Java-Listing angegeben und prompt mit einen Fehler eingebaut: Statt if(1) ist in Java if(true) notwendig.

S. 65 (Tabelle mit Operatoren)

Der Operator für die Matrixmultiplikation lautet @ und nicht &.

S. 81 (Boolesche Werte)

Boolesche Werte werden mit not invertiert, nicht mit dem Tilde-Zeichen ~. Entsprechend muss die vorletzte Zeile des Listings print(not b) lauten.

S. 89 (Tabelle mit String-Funktionen)

Um zu testen, ob das Zeichen s eine bestimmte Eigenschaft hat, verwenden Sie str.isdigit(s), str.isletter(s) usw.

S. 108 (Mit Zeiten rechnen)

Im Listing am Seitenende fehlt eine Zeile zur Initialisierung der Variablen minute. Das vollständige Listing sieht so aus:

from datetime import date, datetime, timedelta
today = datetime.now().date()  # date
week = timedelta(weeks=1)      # timedelta
print(today, today + week, today + 3 * week)
  2018-06-27  2018-07-04  2018-07-18

now = datetime.now()           # datetime
minute = timedelta(minutes=1)  # timedelta (<-- diese Zeile fehlt im Buch)
soon = now + 10 * minute       # datetime
print(now.time(), soon.time())
  17:23:43.116115 17:33:43.116115
S. 113 (verschachtelte Listen)

Die Ausgabe des letzten Beispiels lautet 2, nicht 1 wie im Buch fehlerhaft angegeben.

lst = [[1, 2],  # verschachtelte Liste
       [3, 4]]
lst[0]          # das erste Element ist selbst eine Liste
  [1, 2]
lst[0][1]       # das zweite Element der ersten Teilliste
  2
 ^^^
S. 126 (Sets)

Auf S. 126 unten / S. 127 oben wird die Methode get vorgestellt. Die beiden Absätze und die dazugehörigen Listings gelten allerdings für Dictionaries und nicht für Sets.

S. 177 (Fibonacci-Generator)

Das Listing für die Funktion fibgen enthält mit dem cnt-Test überflüssigen Code. Er beeinträchtigt die Funktion zwar nicht, ist aber für die Funktionsweise unnötig. Das Listing sollte so aussehen:

# die nächste Fibonacci-Zahl mit Generator erzeugen
def fibgen(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a+b
S. 180 (Wiederholungsfrage W3)

Die Punkteanzahl zur Bewertung der Passwörter beim dritten und vierten Passwort stimmt nicht. Korrekt so:

  • 'abc': 0 Punkte
  • 'abcdefghij': 2 Punkte
  • 'ab1122$$!!': 3 Punkte
  • 'abcd1234$!': 4 Punkte
S. 208 (Private Instanzvariablen)

In das Listung auf S. 208 haben sich gleich drei Fehler eingeschlichen. Zum einen fehlt zweimal self, zum anderen muss es in der letzten Zeile MyClass anstelle von Test lauten. Korrekt sieht das Listing so aus:

class MyClass():
    def __init__(self):
        self._privat = 1
        ^^^^^
        self.__nochPrivater = 2
        ^^^^^
obj = MyClass()
print(obj._privat)                 # Ausgabe 1
print(obj._MyClass__nochPrivater)  # Ausgabe 2
           ^^^^^^^
S. 224 (Vererbung)

Die Ausgabe in der letzten Zeile des einführenden Vererbungsbeispiels lautet 3 6 7, nicht 6 6 7.

print(b.m1(), b.m2(), b.m3())  # Ausgabe 3 6 7
S. 225 und S. 226 (Figure-Klasse)

In der letzten Zeile des Listings auf Seite 226 habe ich die Variablen col und row vertauscht. Die Anweisung sieht korrekt so aus:

return 'abcdefgh'[col] + '12345678'[row]

Aufgrund dieses Fehlers stimmt auch die Testausgabe auf S. 225 nicht. Sie muss so aussehen:

# Knight@e5 ['f7', 'g6', 'd7', 'c6', 'f3', 'g4', 'd3', 'c4']
# Bishop@b3 ['a2', 'a4', 'c4', 'c2', 'd5', 'd1', 'e6', 'f7', 'g8']
# Knight@h8 ['g6', 'f7']
S. 288 (Wiederholungsaufgabe W3)

Der Link zu den New-York-Times-Bestsellern hat sich geändert:

<https://api.nytimes.com/svc/books/v3/lists/current/hardcover-fiction.json?api-key=<yourkey>

S. 424 (Wiederholungen zum Kapitel »Zahlen«)

12//7 ergibt natürlich 1, nicht 2.

S. 432 (Wiederholungen W7 »Lorem ipsum« zum Kapitel »Listen, Tupel …«)

Die zweite Lösungsvariante funktioniert ohne Sortieren, das ist ja gerade ihr Vorteil. Die map-Funktion verarbeitet daher words, nicht sortedwords wie im Buch irrtümlich angegeben.

# Variante 2 (viel schneller): reduce und map      
maxlen = reduce(max, map(len, words))
#                             ^^^^^
print('Maximale Wortlänge:', maxlen)       
S. 432 (Wiederholungen W1 »Schaltjahr« zum Kapitel »Verzweigungen und Schleifen«)

Die Bedingung für die Ermittlung der Tage im Februar ist verkehrt herum formuliert, sorry! Richtig sieht der Code so aus:

elif monat == 2:
    tage = 29 if schaltjahr else 28
    #      ^^                    ^^
S. 450 (Wiederholungsaufgabe W3, New-York-Times-Besteller)

Nicht nur die Adresse der Seite hat sich geändert (siehe Hinweis S. 288), sondern auch der Aufbau des JSON-Dokuments. Der korrekte Lösungscode sieht nun so aus:

#!/usr/bin/env python3
import json
import urllib.request
# bitte besorgen Sie sich auf https://developer.nytimes.com/signup einen eigenen Key!
url      = 'https://api.nytimes.com/svc/books/v3/lists/current/hardcover-fiction.json?api-key=<yourkey>'
response = urllib.request.urlopen(url)
binary   = response.read()        # binäre Daten
txt      = binary.decode('utf-8') # als Text interpretieren
top15    = json.loads(txt)
books    = top15['results']['books']
for book in books:
    print('Title:\t', book['title'])
    print('Author:\t', book['author'])
    print('ISBN:\t', book['primary_isbn13'])
    print()

Letzte Änderung 19.2.2021. Vielen Dank an alle Leser, die mir Feedback geben!