--- 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 ![](https://i.imgur.com/Q0RQAiF.png) 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 ![](https://i.imgur.com/pqtQJFK.png) #### 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 ``` ![](https://i.imgur.com/77GD7XO.png) ##### 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** ![](https://i.imgur.com/O2XUG0L.png) • kann zur **Seiteneffekten** kommen ![](https://i.imgur.com/7KxxSrk.png) 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**. ![](https://i.imgur.com/2MCtKt0.png) • Wenn mehrere Referenzen auf die gleiche Instanz zeigen treten **keine direkten Seiteneffekte** auf. ![](https://i.imgur.com/1dNbcOH.png) • Aber Vorsicht: im Objekt befindliche Referenzen auf veränderliche Objekte können geändert werden (wodurch Seiteneffekte entstehen können). ![](https://i.imgur.com/bIUONpl.png) 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 ![](https://i.imgur.com/WywlauX.png) #### Methoden ![](https://i.imgur.com/FhMrZiz.png) ___ ### 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: ![](https://i.imgur.com/n4k4d47.png) ##### Methoden: ![](https://i.imgur.com/5zNqjq0.png) --- ## 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 ``` ![](https://i.imgur.com/fsZAYWv.png) ### 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 ![](https://i.imgur.com/JoZJt9R.png) ___ ## 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 ![](https://i.imgur.com/UGRewZh.png) #### Metazeichen **1. Punkt .** Der Punkt stimmt überein mit jedem beliebigen Zeichen (Ausnahme: Zeilenumbruch). ![](https://i.imgur.com/NpEqMES.png) **2. Zirkumflex ^** Der Zirkumflex stimmt überein mit dem Anfang des Textes ![](https://i.imgur.com/Cd3U6xd.png) **3. Dollarzeichen $** Das Dollarzeichen stimmt überein mit dem Ende des Textes (bzw. einer Zeile). ![](https://i.imgur.com/Fje6JSr.png) **4. Sternchen*** Das Sternchen matcht das null- bis mehrfache Auftreten des vorigen Ausdrucks. * 0 oder mehr ![](https://i.imgur.com/6V17izD.png) **5. Pluszeichen+** Das Pluszeichen matcht das ein- bis mehrfache Auftreten des vorigen Ausdrucks. * 1 oder mehr ![](https://i.imgur.com/D4vUKHg.png) **6. Fragezeichen ?** Das Fragezeichen matcht das null- oder einfache Auftreten des vorigen Ausdrucks. * 0 oder 1 ![](https://i.imgur.com/pAUAOyB.png) **Gierige Quantifizierer** ![](https://i.imgur.com/pdwYgqY.png) * Um die Qualifizierer *, +, ? nicht-gierig (engl. non-greedy, minimal) zu machen, muss ein (weiteres) ? hinter den Qualifizierer gesetzt werden. ![](https://i.imgur.com/kFkpTAo.png) **7. Geschweifte Klammern {}** Die geschweiften Klammern geben an, dass der vorige Ausdruck in einer definierten Anzahl von Kopien auftreten muss. * {m} - m Kopien ![](https://i.imgur.com/ar5vX9F.png) * {m, n} - m bis n Kopien ![](https://i.imgur.com/7vWK9dB.png) * {,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). ![](https://i.imgur.com/Y7zKjpB.png) **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. ![](https://i.imgur.com/47nm9Ke.png) ![](https://i.imgur.com/uFRMtth.png) **10. Senkrechter Strich |** Der senkrechte Strich (Verkettungszeichen, engl. [comp.] pipe) wird zur OderVerbindung beliebiger regulärer Ausdrücke genutzt. ![](https://i.imgur.com/AiLD1WV.png) **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 ![](https://i.imgur.com/rbGUYtR.png) **\zahl** *\zahl* matcht den Inhalt der Gruppe mit der angegebenen Zahl ![](https://i.imgur.com/d5fbsxq.png) #### RegEx in Python ##### Flags ![](https://i.imgur.com/3eVs7Dz.png) ##### Funktionen ![](https://i.imgur.com/fNosVDe.png) ###### 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'] ```