3. Eine informelle Einführung in Python
***************************************

In den folgenden Beispielen werden Eingabe und Ausgabe durch das
Vorhandensein oder Fehlen von Prompts (*>>>* und *...*) unterschieden:
Um das Beispiel nachzuvollziehen, musst du alles eingeben, was nach
dem Prompt steht, sobald dieser erscheint. Zeilen, die nicht mit einem
Prompt beginnen, sind Ausgaben des Interpreters. Beachte, dass ein
zweiter Prompt in einer eigenen Zeile bedeutet, dass du eine Leerzeile
eingeben musst; dies dient dazu, einen mehrzeiligen Befehl zu beenden.

Viele der Beispiele in diesem Handbuch enthalten Kommentare, selbst
wenn sie an der interaktiven Eingabeaufforderung eingegeben werden.
Kommentare beginnen in Python mit dem Raute-Zeichen "#" und erstrecken
sich bis zum Ende der physischen Zeile. Ein Kommentar kann am Anfang
einer Zeile oder nach Leerzeichen oder Code stehen, jedoch nicht
innerhalb eines String-Literals. Ein Raute-Zeichen innerhalb eines
String-Literals ist einfach nur ein Raute-Zeichen. Da Kommentare der
Erklärung von Code dienen und nicht von Python interpretiert werden,
können sie beim Abtippen der Beispiele weggelassen werden.

Einige Beispiele:

   # this is the first comment
   spam = 1  # and this is the second comment
             # ... and now a third!
   text = "# This is not a comment because it's inside quotes."


3.1. Python als Taschenrechner verwenden
========================================

Probieren wir einige einfache Python-Befehle aus. Starte den
Interpreter und warte auf den primären Prompt, ">>>". (Es sollte nicht
lange dauern.)


3.1.1. Zahlen
-------------

The interpreter acts as a simple calculator: you can type an
expression at it and it will write the value.  Expression syntax is
straightforward: the operators "+", "-", "*" and "/" can be used to
perform arithmetic; parentheses ("()") can be used for grouping. For
example:

   >>> 2 + 2
   4
   >>> 50 - 5*6
   20
   >>> (50 - 5*6) / 4
   5.0
   >>> 8 / 5  # division always returns a floating point number
   1.6

Ganzzahlen (z. B. "2", "4", "20") haben den Typ "int", Zahlen mit
Nachkommastellen (z. B. "5.0", "1.6") den Typ "float". Mehr zu
numerischen Typen erfährst du später in diesem Tutorial.

Eine Division ("/") liefert immer eine Gleitkommazahl zurück. Um eine
*Ganzzahldivision* durchzuführen und ein ganzzahliges Ergebnis zu
erhalten, kannst du den Operator "//" verwenden; zur Berechnung des
Restes nutzt du "%":

   >>> 17 / 3  # classic division returns a float
   5.666666666666667
   >>>
   >>> 17 // 3  # floor division discards the fractional part
   5
   >>> 17 % 3  # the % operator returns the remainder of the division
   2
   >>> 5 * 3 + 2  # floored quotient * divisor + remainder
   17

In Python kann der Operator "**" verwendet werden, um Potenzen zu
berechnen [1]:

   >>> 5 ** 2  # 5 squared
   25
   >>> 2 ** 7  # 2 to the power of 7
   128

Das Gleichheitszeichen ("=") wird verwendet, um einer Variablen einen
Wert zuzuweisen. Dabei wird vor dem nächsten interaktiven Prompt kein
Ergebnis angezeigt:

   >>> width = 20
   >>> height = 5 * 9
   >>> width * height
   900

Wenn eine Variable nicht „definiert“ ist (ihr kein Wert zugewiesen
wurde), führt der Versuch, diese zu verwenden, zu einem Fehler:

   >>> n  # try to access an undefined variable
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   NameError: name 'n' is not defined

Gleitkommazahlen werden vollständig unterstützt; Operatoren mit
gemischten Operandentypen wandeln den Ganzzahl-Operanden in eine
Gleitkommazahl um:

   >>> 4 * 3.75 - 1
   14.0

Im interaktiven Modus wird der letzte ausgegebene Ausdruck einer
Variablen "_" zugewiesen. Wenn du Python als Taschenrechner nutzt,
erleichtert dies das Weiterrechnen, zum Beispiel:

   >>> tax = 12.5 / 100
   >>> price = 100.50
   >>> price * tax
   12.5625
   >>> price + _
   113.0625
   >>> round(_, 2)
   113.06

Diese Variable sollte vom Benutzer als schreibgeschützt behandelt
werden. Weise ihr nicht explizit einen Wert zu --- du würdest eine
unabhängige lokale Variable desselben Namens erzeugen, die die
integrierte Variable mit ihrem magischen Verhalten verdeckt.

Neben "int" und "float" unterstützt Python weitere Typen von Zahlen,
wie "Decimal" und "Fraction". Python bietet auch integrierte
Unterstützung für komplexe Zahlen und verwendet das Suffix "j" oder
"J", um den Imaginärteil anzugeben (z. B. "3+5j").


3.1.2. Text
-----------

Neben Zahlen kann Python auch Text verarbeiten (dargestellt durch den
Typ "str", sogenannte "Strings" oder Zeichenketten). Dazu gehören
Zeichen ""!"", Wörter ""rabbit"", Namen ""Paris"", Sätze ""Got your
back."" usw. ""Yay! :)"". Sie können in einfache Anführungszeichen
("'...'") oder doppelte Anführungszeichen (""..."") eingeschlossen
werden, mit dem gleichen Ergebnis [2].

>>> 'spam eggs'  # single quotes
'spam eggs'
>>> "Paris rabbit got your back :)! Yay!"  # double quotes
'Paris rabbit got your back :)! Yay!'
>>> '1975'  # digits and numerals enclosed in quotes are also strings
'1975'

Um ein Anführungszeichen innerhalb eines Strings zu verwenden, müssen
wir es "maskieren", indem ein "\" vorangestellt wird. Alternativ
können wir die andere Art von Anführungszeichen verwenden:

   >>> 'doesn\'t'  # use \' to escape the single quote...
   "doesn't"
   >>> "doesn't"  # ...or use double quotes instead
   "doesn't"
   >>> '"Yes," they said.'
   '"Yes," they said.'
   >>> "\"Yes,\" they said."
   '"Yes," they said.'
   >>> '"Isn\'t," they said.'
   '"Isn\'t," they said.'

In der Python-Shell können die String-Definition und die String-
Ausgabe unterschiedlich aussehen. Die Funktion "print()" erzeugt eine
lesbarere Ausgabe, indem sie die umschließenden Anführungszeichen
weglässt und maskierte sowie Sonderzeichen ausgibt:

   >>> s = 'First line.\nSecond line.'  # \n means newline
   >>> s  # without print(), special characters are included in the string
   'First line.\nSecond line.'
   >>> print(s)  # with print(), special characters are interpreted, so \n produces new line
   First line.
   Second line.

Wenn du nicht möchtest, dass Zeichen mit vorangestelltem "\" als
Sonderzeichen interpretiert werden, kannst du *Raw-Strings* verwenden,
indem du ein "r" vor das erste Anführungszeichen setzt:

   >>> print('C:\some\name')  # here \n means newline!
   C:\some
   ame
   >>> print(r'C:\some\name')  # note the r before the quote
   C:\some\name

Es gibt einen subtilen Aspekt bei Raw-Strings: Ein Raw-String darf
nicht auf eine ungerade Anzahl von "\"-Zeichen enden; siehe den FAQ-
Eintrag für weitere Informationen und Workarounds.

String literals can span multiple lines.  One way is using triple-
quotes: """"..."""" or "'''...'''".  End of lines are automatically
included in the string, but it's possible to prevent this by adding a
"\" at the end of the line.  The following example:

   print("""\
   Usage: thingy [OPTIONS]
        -h                        Display this usage message
        -H hostname               Hostname to connect to
   """)

produces the following output (note that the initial newline is not
included):

   Usage: thingy [OPTIONS]
        -h                        Display this usage message
        -H hostname               Hostname to connect to

Strings können mit dem Operator "+" verknüpft (zusammengefügt) und mit
"*" wiederholt werden:

   >>> # 3 times 'un', followed by 'ium'
   >>> 3 * 'un' + 'ium'
   'unununium'

Zwei oder mehr *String-Literale* (also solche in Anführungszeichen),
die nebeneinanderstehen, werden automatisch verknüpft.

   >>> 'Py' 'thon'
   'Python'

Dieses Feature ist besonders nützlich, wenn du lange Strings umbrechen
möchtest:

   >>> text = ('Put several strings within parentheses '
   ...         'to have them joined together.')
   >>> text
   'Put several strings within parentheses to have them joined together.'

Dies funktioniert jedoch nur mit zwei Literalen, nicht mit Variablen
oder Ausdrücken:

   >>> prefix = 'Py'
   >>> prefix 'thon'  # can't concatenate a variable and a string literal
     File "<stdin>", line 1
       prefix 'thon'
              ^^^^^^
   SyntaxError: invalid syntax
   >>> ('un' * 3) 'ium'
     File "<stdin>", line 1
       ('un' * 3) 'ium'
                  ^^^^^
   SyntaxError: invalid syntax

Wenn du Variablen oder eine Variable und ein Literal verknüpfen
möchtest, verwende "+":

   >>> prefix + 'thon'
   'Python'

Strings können *indiziert* werden (mit Index), wobei das erste Zeichen
den Index 0 hat. Es gibt keinen eigenen Zeichentyp; ein Zeichen ist
einfach ein String der Länge eins:

   >>> word = 'Python'
   >>> word[0]  # character in position 0
   'P'
   >>> word[5]  # character in position 5
   'n'

Indizes können auch negative Zahlen sein, um von rechts zu zählen:

   >>> word[-1]  # last character
   'n'
   >>> word[-2]  # second-last character
   'o'
   >>> word[-6]
   'P'

Beachte, dass negative Indizes bei -1 beginnen, da -0 dasselbe wie 0
ist.

In addition to indexing, *slicing* is also supported.  While indexing
is used to obtain individual characters, *slicing* allows you to
obtain substring:

   >>> word[0:2]  # characters from position 0 (included) to 2 (excluded)
   'Py'
   >>> word[2:5]  # characters from position 2 (included) to 5 (excluded)
   'tho'

Slice-Indizes haben nützliche Standardwerte; ein ausgelassener erster
Index wird standardmäßig auf null gesetzt, ein ausgelassener zweiter
Index entspricht standardmäßig der Länge des verwendeten Strings.

   >>> word[:2]   # character from the beginning to position 2 (excluded)
   'Py'
   >>> word[4:]   # characters from position 4 (included) to the end
   'on'
   >>> word[-2:]  # characters from the second-last (included) to the end
   'on'

Beachte, dass der Startwert immer eingeschlossen und der Endwert immer
ausgeschlossen ist. Dies stellt sicher, dass "s[:i] + s[i:]" immer
gleich "s" ist:

   >>> word[:2] + word[2:]
   'Python'
   >>> word[:4] + word[4:]
   'Python'

Eine Möglichkeit, sich die Funktionsweise von Slices zu merken,
besteht darin, sich die Indizes so vorzustellen, dass sie *zwischen*
die Zeichen zeigen, wobei die linke Kante des ersten Zeichens die
Nummer 0 hat. Die rechte Kante des letzten Zeichens eines Strings mit
*n* Zeichen hat dann den Index *n*, zum Beispiel:

    +---+---+---+---+---+---+
    | P | y | t | h | o | n |
    +---+---+---+---+---+---+
    0   1   2   3   4   5   6
   -6  -5  -4  -3  -2  -1

Die erste Zahlenreihe gibt die Position der Indizes 0...6 im String
an, die zweite Reihe zeigt die entsprechenden negativen Indizes. Der
Slice von *i* bis *j* besteht aus allen Zeichen zwischen den mit *i*
bzw. *j* beschrifteten Kanten.

Für nicht-negative Indizes ist die Länge eines Slices die Differenz
der Indizes, sofern beide innerhalb der Grenzen liegen. Zum Beispiel
beträgt die Länge von "word[1:3]" 2.

Der Versuch, einen zu großen Index zu verwenden, führt zu einem
Fehler:

   >>> word[42]  # the word only has 6 characters
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   IndexError: string index out of range

Außerhalb des Bereichs liegende Slice-Indizes werden beim Slicing
jedoch toleriert:

   >>> word[4:42]
   'on'
   >>> word[42:]
   ''

Python-Strings können nicht verändert werden --- sie sind
*unveränderlich*. Zuweisungen an eine indizierte Position im String
führen daher zu einem Fehler:

   >>> word[0] = 'J'
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: 'str' object does not support item assignment
   >>> word[2:] = 'py'
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: 'str' object does not support item assignment

Wenn du einen anderen String benötigst, solltest du einen neuen
erstellen:

   >>> 'J' + word[1:]
   'Jython'
   >>> word[:2] + 'py'
   'Pypy'

Die integrierte Funktion "len()" gibt die Länge eines Strings zurück:

   >>> s = 'supercalifragilisticexpialidocious'
   >>> len(s)
   34

Siehe auch:

  Text Sequence Type --- str
     Strings sind Beispiele für *Sequenztypen* und unterstützen die
     für solche Typen üblichen Operationen.

  String Methods
     Strings unterstützen eine Vielzahl von Methoden für grundlegende
     Umwandlungen und Suchen.

  f-Strings
     String-Literale, die eingebettete Ausdrücke enthalten.

  Format String Syntax
     Informationen zur Formatierung von Strings mit "str.format()".

  printf-style String Formatting
     Die alten Formatierungsoperationen, die aufgerufen werden, wenn
     Strings der linke Operand des "%"-Operators sind, werden hier
     ausführlicher beschrieben.


3.1.3. Listen
-------------

Python kennt eine Reihe von *zusammengesetzten* Datentypen, die
verwendet werden, um andere Werte zusammenzufassen. Der vielseitigste
ist die *Liste*, die als durch Kommas getrennte Liste von Werten
(Elementen) in eckigen Klammern geschrieben werden kann. Listen können
Elemente verschiedener Typen enthalten, meist haben die Elemente
jedoch denselben Typ.

   >>> squares = [1, 4, 9, 16, 25]
   >>> squares
   [1, 4, 9, 16, 25]

Wie Strings (und alle anderen integrierten *Sequenztypen*) können
Listen indiziert und zerteilt werden:

   >>> squares[0]  # indexing returns the item
   1
   >>> squares[-1]
   25
   >>> squares[-3:]  # slicing returns a new list
   [9, 16, 25]

Listen unterstützen auch Operationen wie die Verkettung:

   >>> squares + [36, 49, 64, 81, 100]
   [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Im Gegensatz zu Strings, die *unveränderlich* sind, sind Listen ein
*veränderlicher* Typ, d. h. ihr Inhalt kann geändert werden:

   >>> cubes = [1, 8, 27, 65, 125]  # something's wrong here
   >>> 4 ** 3  # the cube of 4 is 64, not 65!
   64
   >>> cubes[3] = 64  # replace the wrong value
   >>> cubes
   [1, 8, 27, 64, 125]

You can also add new items at the end of the list, by using the
"list.append()" *method* (we will see more about methods later):

   >>> cubes.append(216)  # add the cube of 6
   >>> cubes.append(7 ** 3)  # and the cube of 7
   >>> cubes
   [1, 8, 27, 64, 125, 216, 343]

Eine einfache Zuweisung kopiert in Python niemals Daten. Wenn du eine
Liste einer Variablen zuweisen, bezieht sich die Variable auf die
*bestehende Liste*. Alle Änderungen, die du an der Liste über eine
Variable vornimmst, sind über alle anderen Variablen sichtbar, die
sich auf sie beziehen.:

   >>> rgb = ["Red", "Green", "Blue"]
   >>> rgba = rgb
   >>> id(rgb) == id(rgba)  # they reference the same object
   True
   >>> rgba.append("Alph")
   >>> rgb
   ["Red", "Green", "Blue", "Alph"]

Alle Slicing-Operationen geben eine neue Liste zurück, die die
angeforderten Elemente enthält. Das bedeutet, dass das folgende
Slicing eine flache Kopie der Liste zurückgibt:

   >>> correct_rgba = rgba[:]
   >>> correct_rgba[-1] = "Alpha"
   >>> correct_rgba
   ["Red", "Green", "Blue", "Alpha"]
   >>> rgba
   ["Red", "Green", "Blue", "Alph"]

Zuweisungen an Slices sind ebenfalls möglich, und dies kann sogar die
Größe der Liste verändern oder sie vollständig leeren:

   >>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
   >>> letters
   ['a', 'b', 'c', 'd', 'e', 'f', 'g']
   >>> # replace some values
   >>> letters[2:5] = ['C', 'D', 'E']
   >>> letters
   ['a', 'b', 'C', 'D', 'E', 'f', 'g']
   >>> # now remove them
   >>> letters[2:5] = []
   >>> letters
   ['a', 'b', 'f', 'g']
   >>> # clear the list by replacing all the elements with an empty list
   >>> letters[:] = []
   >>> letters
   []

Die integrierte Funktion "len()" lässt sich auch auf Listen anwenden:

   >>> letters = ['a', 'b', 'c', 'd']
   >>> len(letters)
   4

Es ist möglich, Listen zu verschachteln (Listen zu erstellen, die
andere Listen enthalten), zum Beispiel:

   >>> a = ['a', 'b', 'c']
   >>> n = [1, 2, 3]
   >>> x = [a, n]
   >>> x
   [['a', 'b', 'c'], [1, 2, 3]]
   >>> x[0]
   ['a', 'b', 'c']
   >>> x[0][1]
   'b'


3.2. Erste Schritte in Richtung Programmierung
==============================================

Natürlich können wir Python für kompliziertere Aufgaben nutzen als
zwei und zwei zusammenzuzählen. Zum Beispiel können wir eine
anfängliche Teilfolge der Fibonacci-Folge wie folgt schreiben:

   >>> # Fibonacci series:
   ... # the sum of two elements defines the next
   ... a, b = 0, 1
   >>> while a < 10:
   ...     print(a)
   ...     a, b = b, a+b
   ...
   0
   1
   1
   2
   3
   5
   8

Dieses Beispiel führt einige neue Funktionen ein.

* Die erste Zeile enthält eine *Mehrfachzuweisung*: Die Variablen "a"
  und "b" erhalten gleichzeitig die neuen Werte 0 und 1. In der
  letzten Zeile wird dies erneut verwendet, was zeigt, dass die
  Ausdrücke auf der rechten Seite alle zuerst ausgewertet werden,
  bevor irgendeine Zuweisung stattfindet. Die Ausdrücke auf der
  rechten Seite werden von links nach rechts ausgewertet.

* Die "while"-Schleife wird ausgeführt, solange die Bedingung (hier:
  "a < 10") wahr bleibt. In Python ist, wie in C, jeder Ganzzahlwert
  ungleich Null wahr; Null ist falsch. Die Bedingung kann auch ein
  String- oder Listenwert sein, tatsächlich jede Sequenz, alles mit
  einer Länge ungleich Null ist wahr, leere Sequenzen sind falsch. Der
  im Beispiel verwendete Test ist ein einfacher Vergleich. Die
  Standard-Vergleichsoperatoren werden genauso geschrieben wie in C:
  "<" (kleiner als), ">" (größer als), "==" (gleich), "<=" (kleiner
  oder gleich), ">=" (größer oder gleich) und "!=" (ungleich).

* Der *Rumpf* der Schleife ist *eingerückt*: Einrückung ist Pythons
  Methode, um Anweisungen zu gruppieren. An der interaktiven
  Eingabeaufforderung musst du für jede eingerückte Zeile einen
  Tabulator oder Leerzeichen eingeben. In der Praxis wirst du
  kompliziertere Eingaben für Python mit einem Texteditor vorbereiten;
  alle guten Texteditoren verfügen über eine automatische Einrückung.
  Wenn eine zusammengesetzte Anweisung interaktiv eingegeben wird,
  muss ihr eine Leerzeile folgen, um den Abschluss anzuzeigen (da der
  Parser nicht erraten kann, wann du die letzte Zeile eingegeben
  hast). Beachte, dass jede Zeile innerhalb eines Basisblocks um
  denselben Abstand eingerückt sein muss.

* The "print()" function writes the value of the argument(s) it is
  given. It differs from just writing the expression you want to write
  (as we did earlier in the calculator examples) in the way it handles
  multiple arguments, floating point quantities, and strings.  Strings
  are printed without quotes, and a space is inserted between items,
  so you can format things nicely, like this:

     >>> i = 256*256
     >>> print('The value of i is', i)
     The value of i is 65536

  Das Schlüsselwort-Argument *end* kann verwendet werden, um den
  Zeilenumbruch nach der Ausgabe zu verhindern oder die Ausgabe mit
  einer anderen Zeichenkette zu beenden:

     >>> a, b = 0, 1
     >>> while a < 1000:
     ...     print(a, end=',')
     ...     a, b = b, a+b
     ...
     0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

-[ Fußnoten ]-

[1] Da "**" eine höhere Rangfolge als "-" hat, wird "-3**2" als
    "-(3**2)" interpretiert und führt somit zu "-9". Um dies zu
    vermeiden und "9" zu erhalten, kannst du "(-3)**2" verwenden.

[2] Anders als in anderen Sprachen haben Sonderzeichen wie "\n" sowohl
    bei einfachen ("'...'") als auch bei doppelten (""..."")
    Anführungszeichen dieselbe Bedeutung. Der einzige Unterschied
    besteht darin, dass du innerhalb einfacher Anführungszeichen """
    nicht maskieren musst (dafür aber "\'") und umgekehrt.
