# Einführung in Python für mathGUIde

Hier finden Sie das Grundwissen über Python, das Sie benötigen, um kreativ mit mathGUIde umzugehen.

## Besonderheiten der Python-Syntax

Zwar ist Python eine vollwertige objektorientierte Sprachen, und mathGUIde macht davon auch regen Gebrauch: Wichtige mathematische Objekte wie z.B. Matrizen oder Polynome sind als Klassen definiert.
Wenn Sie aber einfache Probleme lösen wollen, genüft es meist, diese Klassen passiv zu verwenden und globale Funktionen zu schreiben.
Deshalb folgen nun zwei kleine Funktionsdefinitionen, die ihnen eine Vorstellung von der Python-Proigrammierung geben sollen.

### Beispiel: Der größte gemeinsame Teiler zweier Zahlen

Das folgende Programm missbraucht die Spache Java zur nicht-objektorientierten Programmierung. Es definiert die Funktion `gcd` zur Berechnung des größten gemeinsamen Teilers zweier natürlicher Zahlen (Euklidischer Algorithmus) und testet sie an einem Beispiel. Da Java nur Klassen kennt, muss der Test auch in eine Klasse gepackt werden:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    public class GcdTest {
        static int gcd(int a, int b) {
            while (b != 0) {
                int r = a % b;
                a = b;
                b = r;
            }
            return a;
        }

        public static void main(String[] args) {
            System.out.println(GcdTest.gcd(66, 42));
        }
    }

Hier folgt das Gleiche in Python:

     2
     3
     4
     8
    10
    12
    def gcd(a,b):
        while b != 0:
              a, b = b, a % b
        return a

    print(gcd(66, 42))

Bitte beachten Sie folgende Unterschiede:

- Zeile 2, 3: Hierarchische Syntaxelemente (`class`, `def`, `if`, `elif`, `else`, `while`, `for`) werden in Python nicht durch Klammerung sondern durch Doppelpunkte und logische Einrückung gegliedert.

  Das führt einerseits zu wesentlich besserer Lesbarkeit. Andererseits muss man sehr sorgfältig aufpassen, dass Programme (z.B. beim Verschicken per E-Mail) ihre Einrückungsstruktur nicht verlieren. Um Ihre Programmtexte mit andern mischen zu können, sollten sich beim Einrücken an den Standard halten: 4 Leerzeichen für jeden Einrückungsschritt (keine Tabulatoren!).

  hier sehen Sie ein warnendes Beispiel;

  Java | Python
  --- | ---
      a = 0;
      if (a > 0)
          a += 1;
          a += 2;
      a += 4;
      a = 0
      if a > 0:
          a += 1
          a += 2
      a += 4

  Die Java-Zeilen suggerieren, dass zwei Anweisungen zum `if` gehören. Der Compiler interessiert sich aber nicht für die falsche Einrückung. Nur die erste Anweisung gehört zum `if`. `a` hat also am Ende den Wert 6.
  Da der Python-Compiler die logische Gliederung wirklich der Einrückung entnimmt, wird nur die letzte Anweisung ausgeführt, und `a` hat dann den Wert 4.

- Zeile 2: Python kennt neben Klassen auch globale Funktionen (wie z. B. auch C++).
- Zeile 2: Variablen und Parameter werden in Python nicht deklariert. Sie sind dynamisch typisiert. Das könnte man in Java simulieren, indem alle Variablen als `Object` deklariert werden.
- Zeile 4: Python erlaubt simultane Mehrfachzuweisungen. Dadurch lassen sich oft temporäre Variablen einsparen.

## Listen und List Comprehensions

### Listen, Iteratoren, for-Schleifen

Eine Liste ist in Python eine endliche Reihe von beliebigen Objekten. Diese können einfach in eckigen Klammern aufgezählt werden. Es folgen einige Beispiele:

    polymorpheListe = ["a", 2, [3]]
    quadratzahlen = [1,4,9,16,25]
    for n in quadratzahlen:
        print(n)

Einfache Zahlenfolgen kann man mit der mathGUIde-Funktion `fromTo` generieren:

    # Iteratorfunktion:
    print(fromTo(1,10))

    # Verwendung der Iteratorfunktion:
    l = []
    for i in fromTo(1,10):
        l.append(i)
    print(l)

    # Oder einfacher:
    print(list(fromTo(1,10)))

### Bearbeitung von Listen

    l = [2,4,6]
    l.append(8)        # Element am Ende einfügen
    print(l)
    l.insert(1,3)      # Element an beliebiger Stelle einfügen
    print(l)
    del l[1]           # Element an beliebiger Stelle löschen
    print(l)
    print(l + [10,11]) # Listen verketten

### List Comprehensions

Oft werden Zahlenlisten benötigt, die zwar nach einem einfachen Gesetz aufgebaut sind, aber nicht direkt mit der Funktion `fromTo` erzeugt werden können. Wie kann man z.B. eine Liste der ersten hundert Quadratzahlen erzeugen?

Eine mathematische Schreibweise für die entsprechende Menge wäre

A = \{ n^2 | n \in \{ 1, 2, \ldots, 10 \}\}

Python erlaubt genau diese Schreibweise („List Comprehensions“) für Listen:

    A = [n^2 for n in fromTo(1,10)]

Sogar eine Einschränkung mit bestimmten Bedingungen ist in Python ebenso wie in der Mengenschreibweise möglich:

A = \{ n^2 | n \in \{ 1, 2, \ldots, 100 \}, n \textrm{ ist Primzahl}\}

schreibt sich in mathGUIde so:

    A = [n^2 for n in fromTo(1,100) if isPrime(n)]

Oft ist es nötig, riesige Listen zu durchlaufen. Würde man vor dem Durchlauf die komplette Liste aufbauen, wäre das sehr ineffizient und könnte zu Speicherproblemen führen.
Deshalb werden List Comprehensions nicht als fertige Listen aufgebaut, sondern als Iteratoren, die über `for`-Schleifen durchlaufen werden können.

Auch die mathGUIde-Funktion `fromTo` liefert keine fertige Liste sondern ein iterierbares Objekt.

## Mehr über Python

Eine ausführliche Einführung in Python finden Sie im Python Tutorial.