#' # Lektion 2 #' # #' ## Kopieren #%% a = 1 a #' Zuweisung von b #%% b = a b #' id gibt die Identität aus #%% id(a), id(b) # a und b haben dieselbe Identität #' hier wird b ein neuer Wert zugewiesen #%% b = 2 b #' a bleibt #%% a #' b ist jetzt neu #%% c = 1 id(a), id(b), id(c) #' ## Kopieren II #%% al = [1, 2, [3, 4]] #' bl wird al zugewiesen #%% bl = al #' Jetzt verändern wir die 3 in der Liste [3, 4] und die 2 #%% bl[2][0] = "Hallo" bl[1] = 22 #' Ups #%% al #' Hier wird eine Kopie von al erstellt #%% cl = al[:] cl #' Jetzt ersetzen wir die 1 durch 42 #%% cl[0] = 42 cl #' ok? #%% al #' klappt das? #%% cl[2][0] = 2018 cl #' warum? #%% al #' hier brauchen wir eine deepcopy eine tiefe Kopie #' ## Operationen auf Listen #' max und min #%% zahlen = [1, 2, 3, 1, 5] max(zahlen), min(zahlen) #' append, remove und pop #%% zahlen.append(6) # anfügen zahlen #%% zahlen.remove(1) # entfernt die erste 1 zahlen #%% zahlen.pop(-1) , zahlen # entfernt das letzte Element und gibt es zurück #' ## Boolsche Variablen und Operationen #' wahr #%% True #' falsch #%% False #' und Verknüpfung #%% True and True, True and False # logisches und 'and' #' und Verknüpfung bitweise #%% True & True # bitweises und #' oder Verknüpfung #%% True or False # logisches oder 'or' #' oder Verknüpfung #%% True | False # bitweises or #' Verneinung #%% not True # Negation 'not' #' ## Vergleiche #%% 2 <= 2 2 < 2 #' Gleichheit #%% 1 == 2 #' das geht nicht nur zwischen Zahlen #%% 'a' == 'a', [1, 2] == [2, 3] #' ungleich #%% 1 != 2 #' enthalten sein #%% 2 in zahlen #' ## Verzweigungen, If Anweisungen #' Bedingte Anweisungen (if Anweisungen) dienen dazu, den Programmfluss unter bestimmten Bedingungen verzweigen zu lassen. Damit wird es möglich zur Laufzeit zu entscheiden, ob bestimmte Programmteile ausgeführt werden sollen oder nicht. #' :::python #' if bedinung: #' anweisung #' optional kann man weitere Bedingungen angeben, die überprüft werden, falls die erste nicht erfüllt ist. #%% from numpy.random import rand c = -2+4*rand() print(f'c = {c} zu Anfang') #print('c= ', c, ' zu Anfang') if c > 1: c = c*2 elif c < -1: c = -1 else: c = c**3 print(f'c = {c} zu Ende') #' ## Funktionen #' Mit Funktionen lassen sich Teile eines Programms zusammenfassen. #' Dadurch wird der Programmcode übersichtlicher und weniger anfällig gegenüber #' Fehlern. #' Ein wesentliches Merkmal von Funkttionen ist die Rückgabe von Werten an #' das die Funktion aufrufende Programm. Dazu kann man explizit mit der #' return Anweisung Rückgaben definieren. #' Trifft der Programmablauf innerhalb einer Funktion auf eine return Anweisung, #' so wird die Funktion verlassen und das Objekt zurückgeliefert, #' das in dem Ausdruck der return Anweisung erzeugt wird. #' Funktionen ohne return Anweisungen geben das None-Objekt zurück. #' Funktionen beginnen in Python mit dem Schlüsselwort def gefolgt vom #' Funktionsnamen. In einer Klammer folgen ein oder mehrere Parameter. #' Nach der schließenden Klammer steht ein Doppelpunkt. #' Eingerück stehen in den weiteren Zeilen die Anweisungen. #%% def mysqr2(x): """ Berechnet das Quadrat von x""" y = x**2 return y #' Aufruf #%% mysqr2(2) #' zweites Beispiel #%% def mypow(x): """ Berechnet x**n """ y = x**n # n ist 'global' NICHT verwenden return y n = 1/2 mypow(2) #' besser #%% def mypow(x, m=2): """ Berechnet x**m und, falls m nicht gegeben ist, das Quadrat von x""" y = x**m print(f'erstes m = {m}') m = 42 print(f'm = {m}') return y, m y, m = mypow(2, 3) m #' Achtung ! #%% def f(a, L=[]): print(f'L in der Funktion {L}') L.append(a) return L L = 23 f(1) print(f'L ausserhalb {L}') f([1, 2]) print(f'L ausserhalb {L}') f([1, 2, 3]) #' Erklärung #%% def f(a, L=[]): print(f'L in der Funktion {L}') L.append(a) return L #' Der default Wert wird nur einmal ausgewertet und L ist hier veränderlich L = 'L ausserhalb' print(f'f(1) = {f(1)} : {L}') print(f'f(2) = {f(2)} : {L}') print(f(4, [2, 3, 1])) #' besser mit None statt mit einer veränderlichen Variablen initialisieren #%%: def f(a, L=None): if L is None: L = [] L.append(a) return L print(f(1)) print(f(2)) print(f(3)) print(f(4, [2, 3, 1])) #' Achtung die Rückgabe von append ist None #%% def appendtoemtpylist(a): return [].append(a) L = appendtoemtpylist(1) L #' so klappt es, jetzt hat die leere Liste einen Namen und append verändert L #%% def appendtoemtpylist(a): L = [] L.append(a) return L L = appendtoemtpylist(1) L #' # Rekursionen #' ## erstes Beispiel #' Rekursive Funktionen sind Funktionen, die sich selbst aufrufen. #' Typisches einfaches Beispiel ist die Fakultätsfunktion #' 𝑛!=𝑛(𝑛−1)!, und 0! =1 #%% def factorial(n): if n==0: return 1 return n * factorial(n-1) factorial(4) #' Rekursive Funktionen bestehen aus einer Rekursionsbasis, #'d.h. einer Beschreibung des kleinsten Falls ( 0!=1 ), #' und einem rekursivem Aufruf ( 𝑛!=𝑛(𝑛−1)! ). #%% def factorial(n): print(n) if n==1: return 1 return n * factorial(n-1) factorial(4) #' ## zweites Beispiel #' Wandle eine Zeichenkette aus Ziffern in die zugehörige natürliche Zahl um. #' Das kann int eigentlich schon def atoi(string): assert string.isdigit(), "Die Zeichenkette darf nur Zahlen enthalten" # innere rekursvie Funktion def in_atoi(string, erg): print(f'Zeichenkette {string} Ergebnis {erg}') if len(string) == 0: return 0 if len(string) == 1: return int(string) + (erg * 10) erg = int(string[0]) + (erg * 10) return in_atoi(string[1:], erg) # return in_atoi(string, 0) #' Test #%% string = "11043" print(atoi(string))