---
title: Python
tags: Python, FOM
description: Konzepte des skriptorientierten Programmierens - FOM WI 2019 - Endejan
---
# Python
Konzepte des skriptorientierten Programmierens
WI FOM 3.Semester - Endejan
---
## 1-3 Allgemein
* Interpreter Sprache
* Case-Sensitiv
* C-Python
### Kontrollstrukturen
1. Sequenzen (Einzelanweisungen)
2. Verzweigungen (IF)
3. Schleifen (For, While, ...)
4. Funktionen/Prozeduren
### IO
#### Input
```python=
>>> x = input ('enter a number')
```
#### Output
```python=
>>> print('Hello World')
```
---
## 4 Kontrollstrukturen
### 4.1 Verzweigungen
```python=
if (var1 > var2):
print("Anweisung1")
print("Anweisung2")
```
* Bedingung mit logischen Operatoren: True, False, ==, !=, <, <=, >, >=, not, and, or
```python=
if (var1 > var2):
print("Anweisung1")
print("Anweisung2")
elif (var1 == var2):
print("Alternativanweisungen")
else:
print("Wenn keine Bedingung stimmt")
```
#### Conditional Expression
```python=
b = a**(1/2) if a>0 else "Fehler"
```
### 4.2 Schleifen
#### While
```python=
while (bedingung == True):
#Anweisungsblock
```
* Durch *continue* kann Schleifendurchlauf vorzeitig abgebrochen weerden, nächster fängt direkt an
* Und durch *break* wird Block wirklich vorzeit verlassen
* *else* unnötig, aber möglich
#### For
```python=
l = [1,2,3]
for n in l:
print(n)
#1
#2
#3
```
```python=
for char in "Känguru":
print(char)
'''
K
ä
n
g
u
r
u
'''
```
```python=
#2-er Reihe
for i in range(2,21,2):
print(i)
```
* hier gibt es wie beim while *continue*, *break* und *else*
### 4.3 Operatoren
#### Mathematische Operatoren
* \+
* \-
* \*
* / --> erzeugt immer float
* ()
* ** Exponation
* // Quotient *ganze Zahl ohne Rest*
* % Remainder *Rest*
#### Binäre Operatoren
| Zeichen | Name | Erklärung |
| -------- | -------- | -------- |
| &| Binary AND | 1 wenn beide Bits = 1, ansonsten 0 |
| \| | Binary OR | 1 wenn mind. 1 Bit = 1, (0,0)-> 0, ansonsten 1|
| ^ | Binary XOR | 1 wenn genau 1 Bit = 1, (0,0)-> 0, (1,1) -> 0, ansonsten 1|
| x << n | Bitverschiebung links | Bitverschiebung um n Stellen nach links (*2)|
| x >> n | Bitverschiebung rechts | Bitverschiebung um n Stellen nach rechts (:2)|
| ~x | Bitweises Komplememnt | 1-> 0, 0-> 1|
#### String Operatoren
Funktionieren auch bei Listen
s. sequienzelle Datentypen
### 4.4 Ausnahmebehandlungen: Exeptions
1. Syntax-Fehler / Syntax Error (Parser-Fehler)
• werden beim Parsen einer Zeile entdeckt u. verursachen einen Programmabbruch
• Parser weist auf fehlerhafte Zeile u. erste Stelle, an der der Fehler erkannt wurde
2. Laufzeitfehler / Ausnahmen / Exception
Fehler beim Versuch einen syntaktisch korrekten Befehl auszuführen
• können abgefangen (behandelt) werden
• nicht behandelte Fehler führen zu einem Programmabbruch
• es gibt unterschiedliche Ausnahme-Typen; Fehlermeldung liefert in der letztenZeile Informationen zur Art der konkreten Ausnahme (exception type)
#### try, except
```python=
try:
#Befehl
except:
#Was soll passieren, wenn irgendein Fehler auftritt
```
```python=
try:
c = a/b
except ValueError:
print("DATENTYP nicht zulässig")
except ZeroDivisionError:
print("Division durch NULL nicht möglich")
except:
print("Unerwarteter Fehler")
else:
#try Block wurde fehlerfrei durchlaufen
print(c)
finally:
#Wird am Ende ausgeführt, egal ob Fehler oder nicht
a = b = None
```
---
## 5 Datentypen & Datenstrukturen
### 5.1 Datenmodell
#### Übersicht der eingebauten Datentypen

Python hat **dynamische** und **starke** Typisierung
##### Dynamische Typisierung
* sind nicht an einen bestimmten Datentyp gebunden
* müssen nicht deklariert werden
* Gegenstück statische Typisierung
##### Starke Typisierung
Python Konvertiert aber nicht automatisch, wenn die Variable nicht den gewünschten Datentyp hat
* Gegenstück schwache Typisierung

#### Objekt, Referenz, Instanz
In Python werden alle Daten über **Objekte** (**Instanzen**) bzw. über Beziehungen von Objekten repräsentiert
##### Datenobjekt:
besitzt eine *Id* (Identität), einen *Typ* und einen *Wert*
**1. Identität:**
• Objekt-Id ist eindeutig und unveränderlich
• Abfrage über id()
• Die Id entspricht in CPython der Speicheradresse
*Abfrage:*
```python=
>>> a = 26
>>> id(a)
507099584
```
*Vergleich:*
```python=
>>> a is b
False
```
**2. Typ:**
• Objekt-Typ ist **unveränderlich**
• Abfrage über type()
• bestimmt die möglichen Werte und Operationen
*Abfrage:*
```python=
>>> a = 26
>>> type(a)
#<class 'int'>
```
*Vergleich:*
```python=
>>> type(a)== int
True
```
**3. Wert:**
• Mögliche Werte abhängig vom Typ
*Wertzuweisung*
```python=
>>> a = 26
>>> a
#26
```
*Vergleich:*
```python=
>>> a = 26; b = 26.0
>>> a == b
True
```

##### Referenz:
a referenziert auf die Instanz
##### Instanz:
konkretes Datenobjekt im Speicher (mit eindeutiger Id)
#### Speicherverwaltung
- Python verwaltet die Referenzen auf Instanzen automatisch.
- Wenn es keine Referenz mehr auf eine Instanz gibt, kann der für die Instanz notwendige Speicherplatz vom **Garbage Collector** freigegeben werden.
- Explizite Freigabe über *del*
- Str-Objekt wird direkt nach der Ausgabe wieder freigegeben
#### Mutable & Immutable Datentypen
##### A) Mutable (veränderlich)
- **Wert** der Instanz kann sich zur Laufzeit **ändern**
• **Manipulationen** der Instanzwerte führen **nicht** zur Erzeugung einer **neuen Instanz** -> **Referenz**

• kann zur **Seiteneffekten** kommen

Mutable Datentypen:
1. Listen *list*
2. Mengen *set*
3. Wörterbücher: *dict*
4. Byte-Felder: *bytearray*
##### B) Immutable (unveränderlich)
- **Wert** der Instanz kann sich zur Laufzeit **nicht ändern**
• **Manipulationen** der Instanz führen zur Erzeugung einer **neuen Instanz**.

• Wenn mehrere Referenzen auf die gleiche Instanz zeigen treten **keine direkten Seiteneffekte** auf.

• Aber Vorsicht: im Objekt befindliche Referenzen auf veränderliche Objekte können geändert werden (wodurch Seiteneffekte entstehen können).

Immutable Datentypen:
1. Numerische Objekte *int, float, complex, bool*
2. Zeichenketten *str*
3. Tupel *tuple*
4. Eingefrorene Mengen *frozenset*
5. Bytes *bytes*
---
### 5.2 Spezielle Datentypen
#### NoneType
* Schlüsselwort **None**
* Wahrheitswert ist False
* Abfrage mit is None
```python=
x = None
print(x)
#None
```
```python=
def f():
pass
print(f())
#None
```
___
### 5.3 Numerische datentypen
* immutable
1. Int
2. Bool (Wahrheitswerte, True=1, False=0)
3. Float (Real)
4. Complex - komplexe Zahlen *(z.B. 2 + 8j)*
##### Operatoren
siehe Kapitel Operatoren
##### Typumwandlung
* int()
* bool()
Wandelt man None oder leere Container um, bekommt man Flase zurück
* float()
* complex()
___
### 5.4 Sequenzielle Datentypen
+ Verwaltung von *gleichartigen* oder *verschiedenen *Elementen
+ Die Elemente innerhalb einer Sequenz weisen eine *definierte Reihenfolge* auf.
+ Ein Zugriff auf *einzelne Elemente* einer Sequenz ist über *eindeutige Indizes* möglich
| Datentyp | Verwendungszweck | mutable/immutable |
| -------- | -------- | -------- |
| str | Sequenz von Buchstaben (Zeichenketten) | immutable |
| list |Sequenz beliebiger Instanzen | mutable |
| tuple | Sequenz beliebiger Instanzen | immutable |
| bytes | Sequenz von Bytes (Binärdaten) | immutable |
| bytearray | Sequenz von Bytes (Binärdaten) | mutable |
#### Operatoren für alle sequenzielle Datentypen
Von *allen* sequenziellen Datentypen bereitgestellt
##### 1 Informationen zum Sequenzeninhalt
| Länge | Kleinstes Element | Größtes Element |
| -------- | -------- | -------- |
| len(s) | min(s) | max(s) |
```python=
>>> s = (-1, 2, 4, -17, 210)
>>> len(s)
5
```
##### 2 Slicing
| s[i] | s[i:j] | s[i:j:k] |
| -------- | -------- | -------- |
| Elementzugriff | Slicing | Slicing |
| Element an Stelle i von s (Start bei 0) |Ausschnitt (slice) von s von i bis j| Ausschnitt von s von i bis j mit Schrittweite k |
| Wenn i < 0: Start vom Ende (len(s)+i) | Elemente mit Index k für die gilt: i <= k < j| Elemente mit Index x = i + n*k, so dass 0 <= n < (j-i/k)|
| | Standardwert für i ist 0 |Standardwert für k ist 1 |
```python=
s = list(range(10))
print(s)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(s[3])
#3
print(s[:3])
#[0, 1, 2]
print(s[3:5])
#[3, 4]
print(s[1:8:3])
#[1, 4, 7]
print(s[::2])
#[0, 2, 4, 6, 8]
print(s[-3])
#7
print(s[-1::-2])
#[9, 7, 5, 3, 1]
```
##### 3 Verkettung von Sequenzen
| s + t | s += t | s * n | s *= n |
| -------- | -------- | -------- | -------- |
| Verkettung von s und t |Verkettung von s und t und Zuweisung an s | Verkettung von n flachen Kopien von s | Verkettung von n flachen Kopien von s und Zuweisung an s (Werte < 0 für nwerden als 0 interpretiert) |
```python=
i = list(range(5))
j = list(range(4,11))
print(i + j)
#[0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10]
# i und j bleiben unverändert
i += j
print(i)
#[0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10]
```
```python=
x = "Hallo "
print (x*4)
#Hallo Hallo Hallo Hallo
y = [1,2]
y *= 4
print(y)
#[1, 2, 1, 2, 1, 2, 1, 2]
```
##### 4 Auftreten von Elementen
**a) in / not in**
* x in s
True wenn x in s auftritt
```python=
>>> s = 'Kathy'
>>> 'a' in s
True
```
**b) count**
+ s.count(x)
Anzahl Vorkommnisse x in s
```python=
>>> s = 'Corinna'
>>> x ='n'
>>> s.count(x)
2
```
**c) index**
+ s.index(x) / s.index(x,i,j)
Index des ersten Auftretens von x in s (ab Index i und vor j)
ValueError falls x nicht in s vorkommt!
```python=
>>> s = 'Corinna'
>>> x ='n'
>>> s.count(x)
2
```
```python=
>>> s = 'Corinna'
>>> x ='n'
>>> s.index(x, 5, 7)
5
```
#### Operatoren für veränderbare (mutable) Sequenzen
Die folgenden Operatoren werden von allen veränderbaren sequenziellen Datentypen
bereitgestellt:
##### 1 Ersetzen von Elementen
* s[i] = x
Ersetzt Element an Stelle i mit x
```python=
s = list(range(11))
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
s[0] = 'A'
#['A', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
* s[i:j] = t
Ersetzt s[i:j] durch Inhalt des iterierbaren Objektes t
```python=
s[1:4] = 'BCD'
#['A', 'B', 'C', 'D', 4, 5, 6, 7, 8, 9, 10]
```
* s[i:j:k] = t
Ersetzt Elemente von s[i:j:k] durch Objekte von t (# Elemente
müssen übereinstimmen)
```python=
s[4:9:2] = 'EFG'
#['A', 'B', 'C', 'D', 'E', 5, 'F', 7, 'G', 9, 10]
```
##### 2 Entfernen von Elementen
* del s[i]
Löscht Elemente an Stelle i
```python=
del s[0]
#['B', 'C', 'D', 'E', 5, 'F', 7, 'G', 9, 10]
```
* del s[i:j]
Löscht Ausschnitt [i:j]– entspr. s[i:j]=[reference link]
* del s[i:j:k]
Löscht Elemente von s[i:j:k]
```python=
del s [::2]
#['C', 'E', 'F', 'G', 10]
```
* s.pop([i])
Gibt Element an Stelle i bzw. letztes zurück u. löscht es aus s
```python=
s = list("Corinna")
s.pop()
#'a'
print(s)
#['C', 'o', 'r', 'i', 'n', 'n']
```
* s.remove(x)
Löscht das erste Element in s für das s[i]==x
```python=
s.remove('r')
print(s)
#['C', 'o', 'i', 'n', 'n']
```
* s.clear()
Löscht alle Elemente von s – del s[:]
```python=
s.clear()
print(s)
#[]
```
##### 3 Hinzufügen von Elementen
* s.insert(i, x)
Fügt x an Stelle i bei s ein – s[i:i]=[x]
```python=
s = [2,3,5]
s.insert(0,1)
print(s)
#[1, 2, 3, 5]
```
```python=
s[2:2] = [4] #Wenn Element iterierbar
print(s)
#[1, 2, 4, 3, 5]
```
* s.append(x)
Fügt x an das Ende von von s an – s[len(s):len(s)]=[x]
```python=
s.append([6,7])
#[1, 2, 4, 3, 5, [6, 7]]
```
* s.extend(t)
Erweitert s um die Elemente von t
```python=
s.extend([8,9])
#[1, 2, 4, 3, 5, [6, 7], 8, 9]
```
##### 4 Ändern der Element-Reihenfolge
* s.reverse()
Vertauscht die Elemente von s ‚in place‘
```python=
s = list(range(10))
s.reverse()
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
```
##### 5 Kopieren von Sequenzen
* s.copy()
Erzeugt eine (flache) Kopie von s – s[:]
```python=
t:t = s[1:4].copy()
print("t: {0}, s: {1}".format(t, s))
```
#### Operationen unveränderbare (immutable) Datentypen
#### List
- Datentyp list
• class list([iterable])
• Iterable: eine Sequenz, ein iterierbarer Container oder ein Iterator-Objekt
- Mutable Sequenzen
(typischerweise zur Ansammlung homogener Elemente)
- Erzeugung über
• eckige Klammern (leere Liste): [ ]
• Elemente in eckiger Klammer: [a], [a, b, c]
• List Comprehension: [x for x in iterable]
• Build-in-Funktion list()
- Einige Funktionen liefern Listen zurück, z. B. sorted()
##### Operationen
* alle für mutable definierten Operationen
* UND sort
* sort(*key*=None, *reverse*=None)
Sortierung der Listenelemente
• *key:* Funktion, die zur Ermittlung des Schlüssels genutzt
werden soll (default None: direkte Nutzung der
Elemente); Bsp.: str.lower() für Zeichenketten
• *reverse:* Wahrheitswert; wenn True Sortierung in
umgekehrter Reihenfolge
• Methode gibt stets None zurück! Falls das Ergebnis als
Kopie benötigt wird, kann sorted() verwenden werden
##### List Comprehension
* f(x) for x in S if P(x)]
erzeugt eine Liste, basierend auf den Werten der Sequenz S
• gefiltert durch das Prädikat P und angewendet durch die Funktion f
```python=
grundfarben = ["rot", "gelb", "blau"]
farben = [farben for farben in grundfarben]
print(farben)
['rot', 'gelb', 'blau']
```
Mit Prädiikat (Bedingung):
```python=
grundfarben = ["rot", "gelb", "blau"]
farben = [farben for farben in grundfarben if len(farben) == 4]
print(farben)
['gelb', 'blau']
```
Für Mengen: {} anstatt []
#### Tupel
- Datentyp tuple
• class tuple([iterable])
• Iterable: eine Sequenz, ein iterierbarer
Container oder ein Iterator-Objekt
- Erzeugung über
• runde Klammern (leere Liste): ()
• angehängtes Komma (singleton tuple):
a, oder (a,)
• durch Kommata separierte Elemente:
a, b, c oder (a, b, c)
die Kommata machen das Tupel, nicht die ()!
• Build-in-Funktion tuple(), tuple(iterable)
- Tupel implementieren alle allgemeinen Sequenz-Operationen
- Tupel Packing / Tuple Unpacking
• Objekt in Tupel packen und aus Tupeln entpacken
```python=
# Tupel-Erzeugung
>>> t = (); t
()
>>> t = 1,; t
(1,)
>>> t = (4, 5, 6); t
(4, 5, 6)
>>> tuple("FOM")
('F', 'O', 'M')
>>> l = list("BSc")
>>> l
['B', 'S', 'C']
>>> t = tuple(l); t
('B', 'S', 'c')
# Tupel-Erzeugung
>>> t = (); t
()
>>> t = 1,; t
(1,)
>>> t = (4, 5, 6); t
(4, 5, 6)
>>> tuple("FOM")
('F', 'O', 'M')
>>> l = list("BSc")
>>> l
['B', 'S', 'C']
>>> t = tuple(l); t
('B', 'S', 'c')
```
##### Ranges
• Datentyp range
• class *range(stop)*
• class *range(start, stop[, step])*
• start, stop, step: Ganzzahlen (int)
• Default-Werte: start=0, step=1
• Range-Objekt ist bei ungültigen Werten leer ([] in Bsp.)
• Ranges implementieren alle allgemeinen SequenzOperationen mit Ausnahme der Verkettungen (a + b)
und Wiederholungen (3 * b)
```python=
l = list(range(10))
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l = list(range(4,41, 4))
#[4, 8, 12, 16, 20, 24, 28, 32, 36, 40]
```
#### Zeichenketten
* Datentyp str
* für Zeichenketten und einzelne Zeichen(Unicode Code Points)
* Immutable Datentyp
* Schreibweise mit Hochkommata
• einfaches: 'es sind "Einbettungen" erlaubt'
• doppeltes: "auch hier: 'Einbettung' erlaubt"
• dreifach: ' ' 'drei Mal ' ' ', " " "drei Mal" " "
* Erzeugung über Konstruktur: str()
• class str(object=‘‘)
• \n, \r, \t : New Line, Return, Tabulator
##### Operatoren
###### 1) Trennen von Strings
* s.split(sep=none,maxsplit=-1)
Teilt s bei Vorkommen von sep in entsprechend viele
Elemente. Anzahl Separierungen kann durch maxsplit
begrenzt werden. Suchbeginn: String-Anfang. Ergebnis:
Liste von Strings.
```python=
str = "Ich sitze am Computer und verbessere den Wikipedia Artikel für Ambivalenz. Der ist mir zu eindeutig."
print(str.split())
#['Ich', 'sitze', 'am', 'Computer', 'und', 'verbessere', 'den', 'Wikipedia', 'Artikel', 'für', 'Ambivalenz.', 'Der', 'ist', 'mir', 'zu', 'eindeutig.']
print(str)
#Ich sitze am Computer und verbessere den Wikipedia Artikel für Ambivalenz. Der ist mir zu eindeutig.
```
* s.splitlines([keepends])
Teilt s bei Vorkommen von Zeilenvorschüben.
Zeilenvorschubzeichen bleiben enthalten, wenn
keepends=True.
```python=
str = """'Übrigens, wenn du es vermeiden kannst,' sagt das Känguru, 'dann schüttel diesem Typen da hinten nicht die Hand.'
'Wer ist das?'
'Das ist ein Bankdirektor, der...'
'Okay.'
'Was, okay?'
'Na, das reicht mir schon,' sage ich, 'das kann ich als Grund akzeptieren.'
'Sein Zwillingsbruder ist Asylrichter und will eine neue nationalkonservative Partei gründen.'
'Hui, das klingt ja nach einer sympatischen Familie. Wer war der Vater? Axel Springer?' """
print(str.splitlines())
#["'Übrigens, wenn du es vermeiden kannst,' sagt das Känguru, 'dann schüttel diesem Typen da hinten nicht die Hand.' ", "'Wer ist das?' ", "'Das ist ein Bankdirektor, der...' ", "'Okay.' ", "'Was, okay?' ", "'Na, das reicht mir schon,' sage ich, 'das kann ich als Grund akzeptieren.' ", "'Sein Zwillingsbruder ist Asylrichter und will eine neue nationalkonservative Partei gründen.' ", "'Hui, das klingt ja nach einer sympatischen Familie. Wer war der Vater? Axel Springer?' "]
```
###### 2) Suchen von Teilstrings
* s.find(sub[,start[,end]])
Sucht den String sub im String s. Suchbeginn: StringAnfang; liefert Index des ersten Zeichens oder -1 zurück
```python=
str = "Das Tolle am Internet ist, dass endlich jeder der ganzen Welt seine Meinung mitteilen kann. Das Furchtbare ist, dass es auch jeder tut."
print(str.find("Internet"))
#13
```
* s.index(sub[,start[,end]]) S
ucht den String sub im String s. Suchbeginn: StringAnfang. Wirft Exception, wenn sub nicht in s vorkommt.
```python=
str = "Das Tolle am Internet ist, dass endlich jeder der ganzen Welt seine Meinung mitteilen kann. Das Furchtbare ist, dass es auch jeder tut."
print(str.find("Känguru"))
#-1
print(str.index("Käbguru"))
#ValueError: substring not found
```
* s.count(sub[,start[,end]])
Zählt Anzahl Vorkommnisse von sub in s
```python=
str = "Das Tolle am Internet ist, dass endlich jeder der ganzen Welt seine Meinung mitteilen kann. Das Furchtbare ist, dass es auch jeder tut."
print(str.count("ist"))
#2
```
###### 3) Entfernen bestimmter Zeichen
* s.strip([chars])
Entfernt bestimmte Zeichen am Anfang und am Ende von s. Ohne Angabe von [chars] werden alle Whitespaces (Leerzeichen, Zeilenvorschub, Tabulator) am Anfang/Ende entfernt.
```python=
str = " Ich wollte diesen Körper, und mir war egal was ich dafür tun musste - Donald Trump "
print(str.strip())
#Ich wollte diesen Körper, und mir war egal was ich dafür tun musste - Donald Trump
str = "!Ich wollte diesen Körper, und mir war egal was ich dafür tun musste - Donald Trump!"
print(str.strip("!"))
#Ich wollte diesen Körper, und mir war egal was ich dafür tun musste - Donald Trump
```
###### 4) Ersetzen von Teilstrings
* s.replace(old,new[,count])
Ersetzt Vorkommen von old im String s durch new
```python=
str = "Willst du den Charakter eines Menschen erkennen, so gib ihm Macht"
print(str.replace("Macht", "Schokolade"))
#Willst du den Charakter eines Menschen erkennen, so gib ihm Schokolade
```
* s.lower()
Ersetzt alle Großbuchstaben in s durch entsprechende Kleinbuchstaben
```python=
str = "Willst du den Charakter eines Menschen erkennen, so gib ihm Macht"
print(str.lower())
#willst du den charakter eines menschen erkennen, so gib ihm macht
```
* s.upper()
Ersetzt alle Kleinbuchstaben in s durch entsprechende Großbuchstaben (aus 'ß' wird 'SS')
```python=
str = "Willst du den Charakter eines Menschen erkennen, so gib ihm Macht"
print(str.upper())
#WILLST DU DEN CHARAKTER EINES MENSCHEN ERKENNEN, SO GIB IHM MACHT
```
###### 5) Ausrichten von Strings
* s.center(width[,fillchar])
Zentriert s im resultierenden String
```python=
str = "Mittelfristig"
print(str.center(40))
# Mittelfristig
```
###### 6) Verketten mit String als Teilzeichen
* s.join(seq)
Verkettet die Elemente der Sequenz seq zu einem neuen String, wobei s als Trennzeichen zwischen den Elementen genutzt wird
```python=
liste = ["a", "b", "c"]
print(";".join(liste))
```
###### 7) Weitere Operatoren
* s.encode(encoding='utf-8',errors='strict')
Kodiert die Zeichen in s mit dem angegebenen
Kodierungsverfahren
möglich z. B.:
• 'utf-8'
• 'cp1252'
• 'ascii'
• 'iso-8859-15'
im Fehlerfall z. B. abbrechen (bei errors='strict'), Zeichen ignorieren ('ignore'), ersetzten durch ein Zeichen ('replace').
#### Bytes
* Datentyp bytes
* für Datenströme (Folgen von Bytes)
• bytes ist Folge von Bytes (Werte 0 bis 255)
(str ist Folge von Zeichen mit je n Bytes)
* Datentyp ist immutable (bytearray ist mutable)
* Schreibweise mit Hochkommata (vgl. string)
* Erzeugung vergleichbar mit Erzeugung von strings…
• … allerdings sind nur ASCII-Zeichen erlaubt
• … vor Literale muss ein 'b' geschrieben werden
• … Built-in-Funktion: bytes() (s. Bsp)
```python=
b = b"Folge von Bytes";
#b'Folge von Bytes'
print(type(b))
#<class 'bytes'>
bytes(5)
#b'\x00\x00\x00\x00\x00'
i = bytes(range(65,65+26)); i
#b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
```
#### Bytearray
* Datentyp bytearray
* für Datenströme (Folge von Bytes)
* Datentyp ist mutable (im Gegensatz zu bytes )
* Erzeugung mit Built-in-Funktion bytearray
• … unter Übergabe einer Instanz von bytes
• ... unter Übergabe eines Strings samt encoding
• keine 'literale' Syntax ('b' bei bytes) vorhanden
* Unterstützt die
• allgemeinen Operationen für bytes u. bytearrays
(s. Folgeseite) sowie
• die Operationen für mutable Datentypen (s. o.)
```python=
j = bytearray(b); j
#bytearray(b'Folge von Bytes')
print(type(j))
#<class 'bytearray'>
```
##### Encode() / Decode()
1. String in Byte: str.encode()
2. Byte in String: b.decode()
___
### 5.5 Mengen
* Mengen sind ungeordnete Ansammlungen von paarweise verschiedenen, hashbaren Elementen (jedes Element gibt es in der Menge nur einmal und die Elementdatentypen müssen immutable sein)
* Zwei Basistypen für Mengen:
• set für veränderliche Mengen (mutable)
• frozenset für unveränderliche Mengen (immutable)
* Erzeugung über die Funktionen
• set([iterable])
• frozenset([iterable])
* Nicht-leere Sets können auch über eine Kommaseparierte Liste von Elementen in '{}' erzeugt werden
* Vorteile bei Verwendung von frozenset:
Geschwindigkeit, Speichereffizienz, Verwendbarkeit
als Schlüssel in Dictionaries
```python=
s = set ((1,2,3))
print(type(s))
#<class 'set'>
#Alternative Erzeugung von set !nicht frozenset
s = {1,2,3}
fs = frozenset(("Frage", (47, 3 , 4), 0, b"Hi"))
print(type(fs))
#<class 'frozenset'>
for el in fs:
print(el)
#0
#(47, 3, 4)
#b'Hi'
#Frage
```
#### Operationen

#### Methoden

___
### 5.6 Zuordnungen (Mappings)
#### Dictionarys (Wörterbücher)
* Mappings stellen Zuordnungen zwischen Objekten her
* Datentyp *dict*
* für die Speicherung von **Schlüssel-Wert-Paaren**
* Datentyp ist **mutable**
##### Schlüssel
• müssen im Dictionary eindeutig sein
• müssen Instanzen beliegiger unveränderlicher (immutable) Datentypen sein
##### Werte:
• Instanzen beliebiger Datentypen
```python=
wb ={"eins" : "one", "zwei" : "two", "drei" : "three" }
#Alternativ
wb =dict(eins = "one", zwei = "two", drei = "three")
wx ={"eins" : 1, 2 : "two", (1,2,3) : "Anfang", 4 : [4,5,6,7] }
for schluessel in wx:
print(schluessel, ": ", wx[schluessel])
#2 : two
#(1, 2, 3) : Anfang
#4 : [4, 5, 6, 7]
#eins : 1
```
##### Operationen:

##### Methoden:

---
## 6 Funktionen
Funktionen in Python geben immer einen Wert zurück, wenn nicht durh return definiert kommt None raus
### 6.1 Funktionsdefinition und -aufruf
#### Definition
```python=
def functionName(para1, para2, ...): #Parameter in () = Funktionsschnittstelle
#Ab hier: Funktionskörper
#Anweisung 1
#Anweisung 2
#...
```
#### Aufruf
```python=
functionName(para1, para2, ...)
```
Beispiel:
```python=
def func(foo, bar=None, **sw_args):
pass
func (28, bar = 72, extra = "x")
```
#### Argumente
##### Schlüsselwort-Argument
Übergabe des Arguments mit vorangestelltem
Identifizierer innerhalb des Funktionsaufrufs
und/oder als Wert in einem Dictionary mit
vorangestelltem **
```python=
complex( real=3, imag = 5)
#oder
complex(imag=5, reals = 2)
#oder
complex(**{'real':3, 'imag':5})
```
##### Positions-Argument
Argument, das kein Schlüsselwort-Argument ist.
Übergabe positionsbezogener Argumente am Anfang
der Argumentliste und/oder als Elemente eines
iterierbaren Objekts mit vorangestelltem *
```python=
complex(3,5)
#oder
complex(*(3,5))
```
#### Parametertypen
Es gibt 5 Parametertypen
1. positions- oder schlüsselwortbezogen
- Nach Angabe eines Schlüsselwortparameters keine positionsbezogene Angabe von Argumenten mehr möglich
```python=
def func (foo, bar):
pass
```
3. positionsbezogen mit beliebiger Anzahl
- Aufruf erzeugt ein Tupel mit den übergebenen Argumenten
```python=
def func (*viele_args):
pass
func(1,2,3,4)
#Ausgabe: 1 2 3 4
```
5. schlüsselwortbezogen mit beliebiger Anzahl
- Aufruf erzeugt ein Dictionary mit den übergebenen Argumenten
```python=
def func (**viele_sw_args):
pass
func (a=1, b=2, c=3)
#Ausgabe: {'a':1, 'b':2, 'c':3}
```
7. rein positionsbezogen
- Python bietet keine Syntax zur Definition rein positionsbezogener Parameter
- Position i.d.R. durch Angabe des Parameternamens (Schlüssels) vertauschbar
- Allerdings erlauben einige eingebaute Funktionen nur eine positionsbezogene Übergabe von Parametern (z. B. abs(x))
```python=
abs(a)
```
9. rein schlüsselwortbezogen
- Argumentübergabe ausschließlich über Schlüsselangabe
- Definition in der Parameterliste nach der Angabe der positionsbezogenen Parameter mit beliebiger Anzahl möglich oder – falls es keine solchen gibt – über die Angabe eines einzelnen * (ohne Parametername) vor den rein schlüsselwortbezogenen Parametern
```python=
def func (*, nur_sw1, nur_sw_2):
pass
func(nur_sw_1 = 1, nur_sw_2 = 2)
#Ausgabe: 1 2
```
##### Optionale Parameter
- Haben Standartwerte
- müssen am Ende der Schnittstelle stehen
```python=
#Bar als opt. Parameter
def func (foo, bar = None):
pass
```
#### Argumentlisten: Entpacken
- Iterierbare Objekte können zur Argumentübergabe
'entpackt' werden
• Tupel über einen *
```python=
def func(a,b,c):
print(a+b+c)
t = (7, 9, 11)
func(*t)
#Ausgabe: 27
```
• Dictionaries über zwei **
```python=
d = (a = 1, b = 2, c = 3)
func(**d)
#Ausgabe: 6
```
#### Seiteneffekte
- Bei der Übergabe von Argumenten von
mutable Datentypen kann es zu Seiteneffekten
kommen.
• Argumente werden bei der Übergabe
nicht kopiert
• in der Funktion wird also direkt auf dem
übergebenen Objekt gearbeitet
• Um Seiteneffekte auszuschließen sollten die
Argumente bei der Übergabe ggf. kopiert werden
#### Dokumentation: docstring
Kommentar wird zum Hilfesystem bei der Funktion hinzugefügt:
```python=
def summe(a,b):
"""Liefert Summe von a und b zurück"""
return a+b
```

### 6.2 Namensräume
- Funktionen haben einen eigenen Namensraum
- Unterscheidung
• globaler Namensraum
• werden von gleichnamigen lokalen Variablen überdeckt
• lesender Zugriff aus Funktion heraus möglich
• schreibender Zugriff über Schlüsselwort ***global*** möglich
• lokaler Namensraum
#### Übergeordnete Namensräume
Nicht global und auch nicht lokal
- Innerhalb von Funktionen können weitere Funktionen definiert werden
- dadurch entstehen übergeordnete Namensräume
- Zugriff auf übergeordnete Variablen
• lesender Zugriff ohne weiteres möglich es wird ausgehend vom lokalen Namensraum nach oben hin gesucht, bis die Variable gefunden wurden (globale Variablen werden nicht berücksichtigt)
• **schreibender Zugriff** über Schlüsselwort ***nonlocal*** möglich
```python=
#globale Referenzen
text = "globaler STring"
globale_var = "globale Variable"
def func6():
#Definition der lokalen Variablen
text = "text func6"
zahl = 42
def func6a():
#lesender Zugriff auf globale Var
print("Globale Var: ", globale_var)
#lesender Zugriff auf übergeordnete Var zahl
print("Zahl: ", zahl)
#schreibender Zugriff auf übergeordnete variable text
nonlocal text
text+= "- geändert in func6a"
#lesender Zugriff auf text
print("Text: ", text)
func6a()
func6()
```
### 6.3 lambda
- lambda ist eine **anonyme Inline-Funktion** bestehend aus einem einfachen Ausdruck, der beim Funktionsaufruf ausgewertet wird
- Die Funktion nimmt Parameter entgegen, wertet den Ausdruck aus und liefern den entsprechenden Rückgabewert
- Definition über Schlüsselwort ***lambda***
- Syntax: lambda Argumentliste : Ausdruck
- Die anonyme Funktion kann:
• über einen Verweis angesprochen oder
• direkt verwendet werden
Beispiel:
```python=
namen = (('Kathy', 'Weißenfels'), ('Nele', 'Mersch'), ('Corinna', 'Heinze'))
#Sortierung nach Länge der Vornamen
sorted(namen, key=lambda name: len(name[0]))
#Ausgabe:[('Nele', 'Mersch'), ('Kathy', 'Weißenfels'), ('Corinna', 'Heinze')]
```
```python=
#direkte Verwendung
(lambda x: x+28) (7)
```
```python=
#direkte Verwendung
(lambda x: x+28) (7)
```
### 6.4 eingebaute Funktionen
Alle, die noch nicht in Dokument beschrieben wurden:
* ***reserved(seq)***
Liefert Iterator, der seq rückwärts durchläuft
```python=
prim = (2, 3, 5, 7, 11)
for z in reversed(prim):
print(z, end = ",")
#11,7,5,3,2,
```
* ***all(iterable)***
True, wenn alle Elemente in iterable True
```python=
x = True, False, True
all(x)
#False
x = True, 1 , [0], "FOM"
all(x)
#True
x = False, 0 , [], ""
#(alle) False
```
* ***any(iterable)***
True, wenn mind. ein Element in iterable True
* ***zip(iterables)***
Erzeugt und liefert einen Iterator, der über die Elemente der einzelnen
iterables-Objekte iteriert (zuerst die ersten Elemente der Objekte, dann die
zweiten usw.).
```python=
#Zwei iterierbare Objekte
zahlen = 1,2,3,4
zeichen = 'a', 'b', 'c', 'd'
for zahl, zeich in zip(zahlen, zeichen):
print(zahl, '-', zeich)
#1 - a
#2 - b
#3 - c
#4 - d
verbindung = list(zip(zahlen, zeichen)); verbindung
z,b = zip(*verbindung)
print(z)
#(1, 2, 3, 4)
print(b)
#('a', 'b', 'c', 'd')
```
* ***enumerate(iterable[,start])***
Liefert Aufzählungsiterator für das übergebene (iterierbare) Objekt
```python=
farben = 'magenta', 'rosa', 'pink'
#Liste
list(enumerate(farben))
#[(0, 'magenta'), (1, 'rosa'), (2, 'pink')]
#For Schleife
for nr, farbe in enumerate(farben):
print(nr, '-', farbe)
#0 - magenta
#1 - rosa
#2 - pink
```
* ***round(x[,n])***
Liefert x auf n (bzw. 0) Stellen gerundet
```python=
pi = 3.141592653
print(round(pi))
#3
print(round(pi, 2))
#3.14
```
* ***sum(iterable[, start])***
Liefert die Summe der Elemente in iterable (plus start,
falls gegeben)
```python=
prim = 2, 3, 5, 7, 11
sum(prim)
#28
sum(prim,100)
#128
```
___
## 7 Datein
### Lesen
* Datei öffnen: *datObj = open(datName, "r")*
* Daten zeilenweise lesen: *for zeile in datObj: print(zeile)*
```python=
import os
dateiname = "testdatei.txt"
#Datei öffnen
try:
#um nur zu lesen mit "r" öffnen
dat_obj = open(dateiname, "r")
except (IOError) as e:
print("Fehler:", e.args[1])
os._exit(1)
#Datei lesen
for zeile in dat_obj:
aktuelle_zeile = zeile.strip()
print(aktuelle_zeile)
```
### Schreiben
* Datei öffnen: *datObj = open(datName, **"w"**)*
* Daten schreiben: *datObj.write(zeichenkette)*
```python=
import os
dateiname = "testdatei.txt"
#Datei öffnen
try:
#um nur zu lesen mit "r" öffnen
dat_obj = open(dateiname, "w")
except (IOError) as e:
print("Fehler:", e.args[1])
os._exit(1)
#in Datei schreiben
for i in range(10):
dat_obj.write(str(i)+"\n")
```
### Schließen
* Datei schließen: *datObj.close()*
```python=
#Datei schließen
dat_obj.close()
```
### Öffnen Modi
| "r" | "w" | "a" | "b" | "t" |
| -------- | -------- | -------- | -------- | -------- |
| read: rein lesender Zugriff (default) | write: rein schreibender Zugriff (evtl. vorhandene Datei mit gleichem Dateinamen wird gelöscht) | append: Daten, die in die Datei geschrieben werden, werden am Ende der Datei angehängt | Zusätzliche Angabe zur Bearbeitung einer Datei im Binärmodus ("rb", "r+b", "wb" etc.) | Textmodus (default) |
### Öffnen & Schließen Alternative
* mit Schlüsselwort *with*
* Explizietes Schließen der Datei damit nicht mehr notwendig
```python=
import os
dateiname = "testdatei.txt"
#Datei öffnen (& schließen)
with open(dateiname) as datObj:
#Lesen/Schreiben
```
### Methoden Dateiobjekt

___
## 8 Module der Standartbiblothek
### 8.1 Standartbibilothek - Übersicht
* Die Standardbibliothek wird in Form von **Modulen** bereitgestellt.
* Module können Definitionen (Funktion, Klassen, Konstanten / Variablen) und Anweisungen enthalten (s. u.).
* Zur Verwendung von Modulen müssen diese **importiert** werden (s. u.).
* Module werden auch zur **Modularisierung** eigener Programme genutzt. Programmaspekte können so besser gekapselt und auch in anderen Programmen wiederverwendet werden.
#### Import
```python=
import math
pi = math.pi; pi
#3.141592653589793
```
* Mit dem Schlüsselwort *from* können Elemente – auch einzeln – importiert und anschließend ohne Angabe des Modulnamens, verwendet werden.
```python=
from math import pi, sin
myPi = pi; myPi
#3.141592653589793
```
* Mit dem Schlüsselwort *as* können Objekte oder ganze Module unter einem anderen Namen eingebunden werden
```python=
from math import log2 as lg # Logarithmus zur Basis 2
lg(8)
#3.0
```
### 8.2 Reguläre Ausdrücke (regEx)
Online Tester: https://regex101.com/
* Zum **Suchen** und **Ersetzen** von Zeichen oder Zeichenfolgen (Mustern) in Texten
* Suche von **Übereinstimmungen** (matching)
```python=
import re #Modul für reguläre Ausdrücke
```
#### Einfaches Muster

#### Metazeichen
**1. Punkt .**
Der Punkt stimmt überein mit jedem beliebigen Zeichen (Ausnahme: Zeilenumbruch).

**2. Zirkumflex ^**
Der Zirkumflex stimmt überein mit dem Anfang des Textes

**3. Dollarzeichen $**
Das Dollarzeichen stimmt überein mit dem Ende des Textes (bzw. einer Zeile).

**4. Sternchen***
Das Sternchen matcht das null- bis mehrfache Auftreten des vorigen Ausdrucks.
* 0 oder mehr

**5. Pluszeichen+**
Das Pluszeichen matcht das ein- bis mehrfache Auftreten des vorigen Ausdrucks.
* 1 oder mehr

**6. Fragezeichen ?**
Das Fragezeichen matcht das null- oder einfache Auftreten des vorigen Ausdrucks.
* 0 oder 1

**Gierige Quantifizierer**

* Um die Qualifizierer *, +, ? nicht-gierig (engl. non-greedy, minimal) zu machen, muss ein (weiteres) ? hinter den Qualifizierer gesetzt werden.

**7. Geschweifte Klammern {}**
Die geschweiften Klammern geben an, dass der vorige Ausdruck in einer definierten Anzahl von Kopien auftreten muss.
* {m} - m Kopien

* {m, n} - m bis n Kopien

* {,n} - 0 bis n Kopien
* {m,} - m bis unendlich viele Kopien
**8. Backslash \**
Der Rückstrich (umgekehrter Schrägstrich, engl. Backslash) wird als Escape-Zeichen (Fluchtsymbol) für spezielle Zeichen (z.B. * , +, ?) oder Zeichenfolgen (s.u.) genutzt (also zur Erzeugung von Escape-Sequenzen).

**9. Eckige Klammern[]**
Die eckigen Klammern werden genutzt, um eine Menge von passenden Zeichen anzugeben.
* **Angabe einzelner Zeichen:** [abc] matcht z.B. 'a', 'b', 'c'
* **Angabe von Bereichen:** Zeichen getrennt durch Bindestrich: [a-z] matcht z.B. alle Kleinbuchstaben von 'a' bis 'z‘
* **Komplementbildung:** Definition von Zeichen, die nicht gematcht werden: [^0-9] matcht z.B. alle Zeichen außer die Ziffern '0'bis '9'
* **Spezialzeichen**, wie * , +, (, ), verlieren innerhalb der eckigen Klammern ihre besondere Bedeutung: [+*] matcht z.B. die Zeichen‘+' bis '*‘
* **Zeichenklassen** (s.u.) sind innerhalb der Klammern gültig.


**10. Senkrechter Strich |**
Der senkrechte Strich (Verkettungszeichen, engl. [comp.] pipe) wird zur OderVerbindung beliebiger regulärer Ausdrücke genutzt.

**11. Runde Klammern ()**
Die runden Klammern werden zur Gruppierung genutzt. Der gesamte Ausdruck matcht alles, was innerhalb der Klammern gematcht wird. Auf den Inhalt der Gruppe (den match) kann später erneut zugriffen werden.
* Bsp. s.o.
#### Spezielle Sequenzen

**\zahl**
*\zahl* matcht den Inhalt der Gruppe mit der angegebenen Zahl

#### RegEx in Python
##### Flags

##### Funktionen

###### Match
```python=
import re #Modul für reguläre Ausdrücke
pattern = r"((der|die|das) Nutella)"
string = "das Nutella ist leer"
match = re.match(pattern, string).group(); match
#'das Nutella'
```
```python=
import re #Modul für reguläre Ausdrücke
pattern = r"((der|die|das) Nutella)"
string = "OHH NEIN das Nutella ist leer"
match = re.match(pattern, string).group(); match
#AttributeError: 'NoneType' object has no attribute 'group'
```
###### Search
```python=
import re #Modul für reguläre Ausdrücke
pattern = r"((der|die|das) Nutella)"
string = "OHH NEIN das Nutella ist leer"
match = re.search(pattern, string).group(); match
#'das Nutella'
```
###### Findalll
```python=
import re #Modul für reguläre Ausdrücke
pattern = r"\d{2}.\d{2}.\d{4}" #Datum tt.mm.jjjj
string = "28.02.2000 Corinnas Geburtstag, 05.12.1999 Neles Geburtstag, 02.05.1997 Kais Geburtstag"
match = re.findall(pattern, string); match
#['28.02.2000', '05.12.1999', '02.05.1997']
```