Funktionale Programmierung Klaus Becker 2014. 2 Funktionale Programmierung.
of 65
/65
-
Author
beate-boehlke -
Category
Documents
-
view
114 -
download
2
Embed Size (px)
Transcript of Funktionale Programmierung Klaus Becker 2014. 2 Funktionale Programmierung.
- Folie 1
- Funktionale Programmierung Klaus Becker 2014
- Folie 2
- 2 Funktionale Programmierung
- Folie 3
- 3 Teil 1 Warum funktional programmieren?
- Folie 4
- 4 Ausgangspunkt die Maschine Bei der Entwicklung von Programmiersprachen stand zu Beginn die Steuerung der realen Hardware im Mittelpunkt. Mit einem berschaubaren Befehlssatz konnte man direkt die benutzte Hardware-Maschine programmieren. org 100h start: mov dx,meldung1 mov ah,9h int 021h mov ah, 01h ;Wert ber die Tastatur einlesen int 021h cmp al, '5' jne ende mov dx,meldung2 mov ah,9h int 021h ende: mov ah,4Ch int 21h section.data meldung1: db 'Bitte geben Sie eine Zahl ein:', 13, 10, '$' meldung2: db 13, 10, 'Sie haben die Zahl 5 eingegeben.', 13, 10, '$' Wir orientieren uns im Folgenden nicht an realer Hardware, sonderrn benutzen mit der Registermaschine ein einfaches Maschinenmodell.
- Folie 5
- 5 Registermaschine Registermaschinen enthalten einen Speicher, der aus einzelnen, durchnummerierten Registern besteht, in denen natrliche Zahlen gespeichert werden knnen. > x INC i Erhhe Register i um 1. Gehe zu Zeile x+1. > x DEC i Erniedrige Register i um 1. Gehe zu Zeile x+1. > x JMP i Gehe zu Zeile i. > x TST i Wenn Register i ungleich 0 ist, dann gehe zu Zeile x+1, sonst zu Zeile x+2. > x HLT Beende die Bearbeitung. > 0 TST 1 1 JMP 3 2 JMP 6 3 DEC 1 4 INC 0 5 JMP 0 6 HLT 5 3 0... 0 1 2 Zur Steuerung der Registermaschinen gibt es eine einfache maschinennahe Programmiersprache, die nur die folgenden 5 Befehle kennt:
- Folie 6
- 6 Programmanalyse Aufgabe (a) Kannst du auf den ersten Blick erkennen, was das gezeigte Registermaschinenprogramm leistet? (b) Fhre das Programm aus. Gehe von der folgenden Anfangsbelegung der Register aus: {R0: 0; R1: 4; R2:6; R3:0;...}. Weit du jetzt, was das Programm leistet? Wenn nicht, dann fhre weitere Tests durch. (c) Warum ist es so schwer zu erkennen, was das Programm leistet? 0 TST 1 1 JMP 3 2 JMP 6 3 TST 2 4 JMP 12 5 JMP 9 6 TST 2 7 JMP 18 8 HLT 9 TST 1 10 JMP 16 11 HLT 12 DEC 1 13 DEC 2 14 INC 0 15 JMP 0 16 DEC 1 17 JMP 9 18 DEC 2 19 JMP 6
- Folie 7
- 7 Spaghetti-Code Maschinennahe Programmiersprachen nutzen Sprungbefehle (wie z.B. JMP), um Wiederholungen zu realisieren. 0 TST 1 1 JMP 3 2 JMP 6 3 TST 2 4 JMP 12 5 JMP 9 6 TST 2 7 JMP 18 8 HLT 9 TST 1 10 JMP 16 11 HLT 12 DEC 1 13 DEC 2 14 INC 0 15 JMP 0 16 DEC 1 17 JMP 9 18 DEC 2 19 JMP 6 0 TST 1 1 JMP 3 2 JMP 6 3 TST 2 4 JMP 12 5 JMP 9 6 TST 2 7 JMP 18 8 HLT 9 TST 1 10 JMP 16 11 HLT 12 DEC 1 13 DEC 2 14 INC 0 15 JMP 0 16 DEC 1 17 JMP 9 18 DEC 2 19 JMP 6 Sprungbefehle knnen leicht dazu fhren, dass Programme vllig undurchschaubar werden. Im gezeigten Programm fhren die Sprungbefehle zu einer Art Spaghetti-Code, bei dem die Ablauflogik nicht leicht zu entwirren ist. Ablaufmodellierung mit Sprungbefehlen Spaghetti-Code
- Folie 8
- 8 Verzicht auf Sprungbefehle Schon frh erkannte man die Schwche von Sprungbefehlen und versucht seither, auf hheren Programmierebenen mglichst auf die Verwendung solcher Befehle zu verzichten. Strukturierte Programmierung benutzt keine Sprungbefehle zur Ablaufmodellierung, sondern Kontrollstrukturen, die bestimmte Ablaufmuster vorgeben. while (R1 != 0) and (R2 != 0): R0 = R0 + 1 R1 = R1 - 1 R2 = R2 - 1 while R1 != 0: R1 = R1 - 1 while R2 != 0: R2 = R2 - 1 Im Programm wird die Kontrollstruktur "Wiederholung mit Eintrittsbedingung" (dargestellt durch eine while-Schleife) zur Modellierung benutzt. Kontrollstrukturen erhhen die Transparenz der Ablauflogik und verringern die Fehlerquote bei der Entwicklung von Programmen. Ablaufmodellierung mit Kontrollstrukturen
- Folie 9
- 9 Prozeduren Als Weiterentwicklung von hardwareorientierten Programiersprachen knnen die prozeduralen Programmiersprachen angesehen werden. Hier knnen Sequenzen von Anweisungen zu Prozeduren zusammengefasst werden, die dann als Befehle fr eine abstraktere, hypothetische Maschine gedeutet werden knnen. program bsp ! implicit none real :: x, y, z write( *, * ) 'x -> ' read( *, * ) x call sub( x, y, z ) write( *, * ) 'y -> ', y, 'z -> ', z end subroutine sub( a, b, c ) ! implicit none real :: a, b, c b = a**2 c = a**2 + b end subroutine sub
- Folie 10
- 10 Programmanalyse Aufgabe (a) Was leistet die Prozedur minimum? (b) Ergnze den Python-Dialog. (c) Was ist an der gezeigten Vorgehensweise problematisch? def minimum(a, b): global m while (a != 0) and (b != 0): m = m + 1 a = a - 1 b = b - 1 >>> m = 0 >>> minimum(5, 8) >>> m >>> minimum(7, 2) >>> m
- Folie 11
- 11 Seiteneffekte Das Unterprogramm auf der linken Seite verndert den Wert einer globalen Variablen. Das Unterprogramm hat einen sog. Seiteneffekt. >>> m = 0 >>> minimum(5, 8) >>> m 5 >>> minimum(7, 2) >>> m 7 Unterprogramm mit Seiteneffekt def minimum(a, b): global m while (a != 0) and (b != 0): m = m + 1 a = a - 1 b = b - 1 Seiteneffekte fhren dazu, dass das Verhalten von Funktionen schwer zu durchschauen ist. Insbesondere bei komplexeren Programmen verliert man leicht den berblick, welche (beabsichtigten und auch unbeabsichtigten) Nebenwirkungen ein Funktionsaufruf mit Seiteneffekten hat. Man versucht daher, Seiteneffekte mglichst zu vermeiden.
- Folie 12
- 12 Vermeidung von Seiteneffekten Eine Mglichkeit besteht darin, die Verantwortung fr seiteneffektfreie Programme dem Programmentwickler zu berlassen. Dieser muss dann dafr Sorge tragen, dass keine Bausteine mit Seiteneffekten erstellt werden. Eine andere Mglichkeit besteht darin, die Programmiersprache so zu konzipieren, dass keine Seiteneffekte mehr mglich sind. Funktionale Programmierung ist (zumindest in der strengen Version) so konzipiert, dass keine Seiteneffekte auftreten knnen und dass referentielle Transparenz stets gewhrleistet ist.
- Folie 13
- 13 Referentielle Transparenz >>> minimum(5, 8) 5 >>> m = 0 >>> minimum(5, 8) >>> m 5 >>> minimum(5, 8) >>> m 10 Unterprogramm mit Seiteneffekt def minimum(a, b): m = 0 while (a != 0) and (b != 0): m = m + 1 a = a - 1 b = b - 1 return m def minimum(a, b): global m while (a != 0) and (b != 0): m = m + 1 a = a - 1 b = b 1 Funktion ohne Seiteneffekt Referentielle Transparenz liegt vor, wenn ein Teilausdruck - unabhngig von seiner Position innerhalb eines Ausdrucks und unabhngig vom Zeitpunkt der Auswertung - immer denselben Wert hat. keine referentielle Transparenz
- Folie 14
- 14 Dialog ber Seiteneffekte I: Hallo! Ich vertrete hier die imperative Programmierung. F: Hallo, und ich vertrete die funktionale Programmierung. I: Stimmt es, dass du keine Seiteneffekte erlaubst? F: Ja, so ist es. I: Und wie machst du das? F: Seiteneffekte entstehen durch Zuweisungen an globale Variablen. Bei mir gibt es gar keine Zuweisungen mehr. Dann kann man auch nicht in die Verlegenheit kommen, einer globalen Variablen etwas zuzuweisen. I: Klingt einfach. Aber, wie soll man dann einen so einfachen Vorgang wie den folgenden ohne Zuweisungen beschreiben? F: Man muss es halt ganz anders machen. I: Das kann ich mir nicht so recht vorstellen. Wenn es keine Zuweisungen gibt, dann macht es auch keinen groen Sinn, Variablen einzufhren. Man hat ja keine Mglichkeit, den Wert der Variablen zu verndern. Und wenn man Werte von Variablen nicht verndern kann, dann kann man es durch Anweisungen im Schleifenkrper auch nicht erreichen, dass die Abbruchbedingung einer SOLANGE-Schleife erfllt wird. Das macht ja alles keinen Sinn mehr. F: Wieso bist du so auf Variablen und Schleifen fixiert? I: Variablen bentigt man ja wohl zur Datenverwaltung und ohne Schleifen gibt es keine Wiederholungen. Oder sehe ich das ganz falsch? F: Ja, das siehst du etwas zu eng. Wenn du wissen willst, wie mein Berechnungskonzept funktioniert, dann musst du dir den nchsten Abschnitt anschauen. ALGORITHMUS Summenberechnung: {vorher: n aus N} setze s auf 0 setze i auf 0 SOLANGE i 1;1+0->1;1+1->1 """ s = i+j if s == 2: s = 1 return s def addBilder(M, N): """ die Bitfolgen in M und N werden Bit fr Bit addiert """ L = [] for i in range(len(M)): if i < 3: L = L + [M[i]] else: L = L + [addBit(M[i], N[i])] return L">
- 15 Exkurs: Seiteneffekte bei Objekten def invertiereBild(L): """ das in L dargestellte Bild wird invertiert d.h.: aus 0 wird 1 und aus 1 wird 0 """ for i in range(3, len(L)): if L[i] == 0: L[i] = 1 else: L[i] = 0 return L def addBit(i, j): """ die Bits i, j werden add.: 0+0->0;0+1->1;1+0->1;1+1->1 """ s = i+j if s == 2: s = 1 return s def addBilder(M, N): """ die Bitfolgen in M und N werden Bit fr Bit addiert """ L = [] for i in range(len(M)): if i < 3: L = L + [M[i]] else: L = L + [addBit(M[i], N[i])] return L
- Folie 16
- 16 Exkurs: Seiteneffekte bei Objekten >>> bild = ['P1', 3, 3, 1, 1, 1, 1, 0, 1, 1, 1, 1] >>> negativ = invertiereBild(bild) >>> negativ ['P1', 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0] >>> neuesBild = addBilder(bild, negativ) >>> neuesBild ??? Aufgabe: Was erwartest du als Ergebnis beim Testdialog? Warum erhlt man ein anderes Ergebnis?
- Folie 17
- 17 Teil 2 Funktionen als Programmierbausteine
- Folie 18 >> Gewicht in kg: 70 Gre in m: 1.70 BMI: 24.2214532872 >>> bmi(70, 1.70) 24.221453287197235 Eingabe der Datenbergabe der Daten Ausgabe der Daten Rckgabe der Daten Wir ersetzen die Eingabe von Daten (durch einen Benutzer) durch die abstraktere Datenbergabe und die Ausgabe der Daten (auf dem Bildschirm) durch die abstraktere Datenrckgabe und konzentrieren uns strker auf die Verarbeitung der Daten.">
- 18 Datenverarbeitung mit Funktionen def bmi(gewicht, groesse): return \ gewicht/(groesse*groesse) Beispiel: BMI-Berechnung # Eingabe gewicht = float(input("..: ")) groesse = float(input("..: ")) # Verarbeitung bmi = gewicht / (groesse * groesse) # Ausgabe print("BMI:", bmi) >>> Gewicht in kg: 70 Gre in m: 1.70 BMI: 24.2214532872 >>> bmi(70, 1.70) 24.221453287197235 Eingabe der Datenbergabe der Daten Ausgabe der Daten Rckgabe der Daten Wir ersetzen die Eingabe von Daten (durch einen Benutzer) durch die abstraktere Datenbergabe und die Ausgabe der Daten (auf dem Bildschirm) durch die abstraktere Datenrckgabe und konzentrieren uns strker auf die Verarbeitung der Daten.
- Folie 19
- 19 Funktionale Programme def bmi(gewicht, groesse): return \ gewicht/(groesse*groesse) Eine Funktion ist eine Einheit, die bergebene Daten verarbeitet und den berechneten Funktionswert als Ergebnis zurckgibt. Die Verarbeitung wird ber eine Funktionsdefinition (man sagt oft auch Funktionsdeklaration) festgelegt. Aktiviert wird eine Verarbeitung durch einen Funktionsaufruf. >>> bmi(70, 1.70) 24.221453287197235 Funktiondefinition Funktionsaufruf Ein funktionales Programm besteht aus einer oder mehrerer Funktionsdefinitionen und einem Funktionsaufruf. Eine Funktionsdefinition leistet folgende Festlegungen: die Festlegung der Datenbergabe mit Hilfe von Parameter, die Festlegung der Datenverarbeitung und die Festlegung der Datenrckgabe. Bei einem Funktionsaufruf werden die Parameter mit konkreten Werten versehen. Diese Daten werden dann nach den Festlegungen in der Funktionsdefinition verarbeitet. Abschlieend wird ein Funktionswert als Ergebnis zurckgeliefert.
- Folie 20
- 20 Funktionale Programme In einem rein funktionalen Programm drfen in den Funktionsdefinitionen auer den Parametern keine weiteren Variablen vorkommen. In der Funktionsdefinition kommen dann auch keine Zuweisungen vor. Hierdurch wird gewhrleistet, dass keine Seiteneffekte zustande kommen knnen. def wegberechnungen(geschwindigkeit): return ((geschwindigkeit/10)*3, (geschwindigkeit/10)**2, (geschwindigkeit/10)*3 + (geschwindigkeit/10)**2) rein funktionales Programm Schwierigkeit: Teilausdrcke wie (geschwindigkeit/10)*3 und (geschwindigkeit/10)**2 kommen mehrfach in der Berechnungsvorschrift vor und mssen bei der Ausfhrung gegebenenfalls mehrfach berechnet werden. Das ist ineffizient.
- Folie 21
- 21 Lokale Bindungen def wegberechnungen(geschwindigkeit): reaktionsweg = (geschwindigkeit/10)*3 bremsweg = (geschwindigkeit/10)**2 anhalteweg = reaktionsweg + bremsweg return (reaktionsweg, bremsweg, anhalteweg) Ein Ausweg ergibt sich, wenn wir Variablen als lokale Konstanten verwenden. Das bedeutet, dass Variablen nur lokal innerhalb von Funktionsdefinitionen vorkommen drfen und dass ihnen nur ein einziges mal ein Wert zugewiesen werden darf. Auf der rechten Seite einer Zuweisung darf dann die Variable, die auf der linken Seite der Zuweisung steht, nicht vorkommen. Man spricht in diesem Zusammenhang auch von lokalen Bindungen. def wegberechnungen(geschwindigkeit): return ((geschwindigkeit/10)*3, (geschwindigkeit/10)**2, (geschwindigkeit/10)*3 + (geschwindigkeit/10)**2) keine (neuen) Variablen nur lokale Bindungen
- Folie 22
- 22 Lokale Bindungen def wegberechnungen(geschwindigkeit): reaktionsweg = (geschwindigkeit/10)*3 bremsweg = (geschwindigkeit/10)**2 anhalteweg = reaktionsweg + bremsweg return (reaktionsweg, bremsweg, anhalteweg) Mit lokalen Bindungen wird ein Term lokal (d.h. innerhalb der Funktionsdefinition) an einen Namen gebunden, so dass man diesen Namen an Stelle des Terms benutzen kann. Funktionale Programme mit lokalen Bindungen kann man also jederzeit in streng funktionale Programme umwandeln, ohne das Verhalten des Programms zu verndern. Evtl. wird nur die Berechnungszeit hierdurch beeinflusst. Funktionale Programme mit lokalen Bindungen erzeugen also keine Seiteneffekte und sind - genau wie rein funktionale Programme - referentiell transparent. def wegberechnungen(geschwindigkeit): return ((geschwindigkeit/10)*3, (geschwindigkeit/10)**2, (geschwindigkeit/10)*3 + (geschwindigkeit/10)**2) keine (neuen) Variablen nur lokale Bindungen
- Folie 23
- 23 Funktionskomposition def erstesZeichen(wort): return wort[0] def ohneErstesZeichen(wort): return wort[1:] def mitLetztemZeichen(wort, \ zeichen): return wort + zeichen Beispiel: erstes Zeichen eines Wortes ans Ende verschieben # Eingabe wort = input('Wort: ') # Verarbeitung # entferne das erste Zeichen erstesZeichen = wort[0] wort = wort[1:] # fge es am Ende des Worts ein wort = wort + erstesZeichen # Ausgabe print(wort) mehrere Aktionen hintereinander ausfhren >>> mitLetztemZeichen(ohneErstesZeichen('TOR'), erstesZeichen('TOR')) 'OR' 'T' 'ORT' Funktionsaufrufe ineinander schachteln
- Folie 24
- 24 Funktionskomposition def erstesZeichen(wort): return wort[0] def ohneErstesZeichen(wort): return wort[1:] def mitLetztemZeichen(wort, zeichen): return wort + zeichen def erstesZeichenAlsLetztesZeichen(wort): return mitLetztemZeichen(ohneErstesZeichen(wort), \ erstesZeichen(wort)) Beispiel: Zeichen innerhalb eines Wortes verschieben Bei der Komposition bzw. Verkettung von Funktionen werden Funktionen ineinandergeschachtelt aufgerufen. Aufgabe: Lse die Probleme in (a) und (b) analog mit einer Funktion, die geeignete Hilfsfunktionen benutzt. (a) In einer nicht-leeren Zeichenkette soll das letzte Element ganz an an den Anfang der Zeichenkette gesetzt werden. Aus 'ORT' soll so 'TOR' erzeugt werden. (b) In einer nicht-leeren Zeichenkette soll das erste mit dem letzten Zeichen ausgetauscht werden. Aus 'TOR' soll so 'ROT' erzeugt werden.
- Folie 25
- 25 Fallunterscheidungen def ohneErstesZeichen(wort): if wort != '': return wort[1:] else: return '' Beispiel: erstes Zeichen eines Wortes entfernen WENN das Wort Zeichen enthlt: entferne das erste Zeichen SONST: tue nichts Fallunterscheidung Funktionsdefinition mit Fallunterscheidung Bei einer Funktionsdefinition mit Fallunterscheidung werden die Funktionswerte fr verschiedene Flle (evtl. unterschiedlich) festgelegt. Aufgabe: Lse die folgenden Probleme mit geeigneten Hilfsfunktionen. Dabei soll auch bercksichtigt werden, dass das Ausgangswort eventuell keine Zeichen enthlt. (a) In einer nicht-leeren Zeichenkette soll das letzte Element ganz an an den Anfang der Zeichenkette gesetzt werden. Aus 'ORT' soll so 'TOR' erzeugt werden. (b) In einer nicht-leeren Zeichenkette soll das erste mit dem letzten Zeichen ausgetauscht werden. Aus 'TOR' soll so 'ROT' erzeugt werden.
- Folie 26
- 26 Wiederholungen Eingabe: wort altesWort = wort neuesWort = '' SOLANGE altesWort noch Zeichen enthlt: fge das erste Zeichen von altesWort vorne in neuesWort ein entferne das erste Zeichen von altesWort Ausgabe: neuesWort Beispiel: Wrter umdrehen {neuesWort -> ''; altesWort -> 'LEBEN'} neuesWort = altesWort[0] + neuesWort altesWort = altesWort[1:] {neuesWort -> 'L'; altesWort -> 'EBEN'} neuesWort = altesWort[0] + neuesWort altesWort = altesWort[1:] {neuesWort -> 'EL'; altesWort -> 'BEN'} neuesWort = altesWort[0] + neuesWort altesWort = altesWort[1:] {neuesWort -> 'BEL'; altesWort -> 'EN'} neuesWort = altesWort[0] + neuesWort altesWort = altesWort[1:] {neuesWort -> 'EBEL'; altesWort -> 'N'} neuesWort = altesWort[0] + neuesWort altesWort = altesWort[1:] {neuesWort -> 'NEBEL'; altesWort -> ''} iterativer Lsungsansatz (benutzt Variablen und eine Schleife)
- Folie 27
- 27 Rekursion Beispiel: Wrter umdrehen umdrehen('LEBEN') -> (umdrehen('EBEN') + 'L') -> ((umdrehen('BEN') + 'E') + 'L') -> (((umdrehen('EN') + 'B') + 'E') + 'L') -> ((((umdrehen('N') + 'E') + 'B') + 'E') + 'L') -> (((((umdrehen('') + 'N') + 'E') + 'B') + 'E') + 'L') -> ((((('' + 'N') + 'E') + 'B') + 'E') + 'L') -> (((('N' + 'E') + 'B') + 'E') + 'L') -> ((('NE' + 'B') + 'E') + 'L') -> (('NEB' + 'E') + 'L') -> ('NEBE' + 'L') -> 'NEBEL' rekursiver Lsungsansatz (benutzt Problemreduktionen und Funktionskomposition)
- Folie 28
- 28 Rekursion Beispiel: Wrter umdrehen umdrehen('LEBEN') -> (umdrehen('EBEN') + 'L') -> ((umdrehen('BEN') + 'E') + 'L') -> (((umdrehen('EN') + 'B') + 'E') + 'L') -> ((((umdrehen('N') + 'E') + 'B') + 'E') + 'L') -> (((((umdrehen('') + 'N') + 'E') + 'B') + 'E') + 'L') -> ((((('' + 'N') + 'E') + 'B') + 'E') + 'L') -> (((('N' + 'E') + 'B') + 'E') + 'L') -> ((('NE' + 'B') + 'E') + 'L') -> (('NEB' + 'E') + 'L') -> ('NEBE' + 'L') -> 'NEBEL' Problemreduktionsmuster: Fall 1: wort == '' umdrehen(wort) -> wort Fall 2: wort != '' umdrehen(wort) -> umdrehen(wort[1:]) + wort[0] def umdrehen(wort): if len(wort) == 0: return '' else: return umdrehen(wort[1:]) + wort[0] rekursive Funktionsdefinition
- Folie 29
- 29 Rekursion Rekursive Problemreduktion ist eine Problemlsestrategie, bei der ein Problem auf ein strukturgleiches Problem (in "verkleinerter" Form) zurckgefhrt wird. Eine rekursive Funktionsdefinition ist eine Funktionsdefinition, bei der die Funktion selbst im Funktionsterm benutzt wird. def umdrehen(wort): if len(wort) == 0: return wort else: return umdrehen(wort[1:]) + wort[0]
- Folie 30 (umdrehen('EBEN') + 'L') -> ((umdrehen('BEN') + 'E') + 'L') -> (((umdrehen('EN') + 'B') + 'E') + 'L') -> ((((umdrehen('N') + 'E') + 'B') + 'E') + 'L') -> (((((umdrehen('') + 'N') + 'E') + 'B') + 'E') + 'L') -> ((((('' + 'N') + 'E') + 'B') + 'E') + 'L') -> (((('N' + 'E') + 'B') + 'E') + 'L') -> ((('NE' + 'B') + 'E') + 'L') -> (('NEB' + 'E') + 'L') -> ('NEBE' + 'L') -> 'NEBEL'">
- 30 Ausfhrung rekursiver Funktionsdef. Bei der Auswertung von Funktionsaufrufen kommt es bei rekursiven Funktionsdefinitionen zur wiederholten Ausfhrung strukturgleicher Reduktionsschritte. Rekursion kann somit als Ersatz fr die Kontrollstruktur "Wiederholung" benutzt werden. Damit dieses Wiederholungskonzept terminiert, muss nach endlichen vielen Reduktionsschritten eine Situation erreicht werden, bei der die Lsung zum Problem direkt angegeben werden kann. Man versucht daher, Reduktionsschritte so zu konzipieren, dass sie das Problem in einer Weise "verkleinern", die nur endlich viele Verkleinerungsschritte zulsst. Rekursion ist eine mchtige und gerne genutzte Strategie beim Problemlsen. Wenn der Problemkontext es zulsst, dann kann man das Problemlseverfahren sehr einfach und kompakt ber eine Problemreduktion beschreiben. Die wiederholte Ausfhrung der Reduktionsschritte - und damit die Erzeugung der Lsung - berlsst man dem Ausfhrsystem. umdrehen('LEBEN') -> (umdrehen('EBEN') + 'L') -> ((umdrehen('BEN') + 'E') + 'L') -> (((umdrehen('EN') + 'B') + 'E') + 'L') -> ((((umdrehen('N') + 'E') + 'B') + 'E') + 'L') -> (((((umdrehen('') + 'N') + 'E') + 'B') + 'E') + 'L') -> ((((('' + 'N') + 'E') + 'B') + 'E') + 'L') -> (((('N' + 'E') + 'B') + 'E') + 'L') -> ((('NE' + 'B') + 'E') + 'L') -> (('NEB' + 'E') + 'L') -> ('NEBE' + 'L') -> 'NEBEL'
- Folie 31
- 31 Modularisierung Fazit: Funktionale Programmierung setzt konsequent das Modularisierungsprinzip um. Modularisierung bedeutet, ein Gesamtsystem nach dem Baukastenprinzip aus Einzelbausteinen (den sogenannten "Modulen") zusammenzusetzen. Funktionen knnen als Bausteine angesehen werden, die man mit Hilfe von Funktionskomposition flexibel zusammensetzen kann. Wenn sie - wie in der funktionalen Programmierung blich - frei von Seiteneffekten konzipiert werden, dann knnen die Bausteine unabhngig genutzt werden.
- Folie 32
- 32 Aufgaben Aufgabe: Wir betrachten die Berechnung der Summe natrlicher Zahlen. ALGORITHMUS Summenberechnung: {vorher: n aus N} setze s auf 0 setze i auf 0 SOLANGE i 0 summe(5) -> 5 + summe(4) iterative Lsungrekursive Lsung Entwickle und teste eine hierzu passende Funktionsdefinition.
- Folie 33
- 33 Aufgaben Aufgabe: Ein Kapital von 1000 Euro wird jhrlich mit 5% verzinst. Die Funktion kapital(n) beschreibe den Kapitalwert nach n Jahren. Die folgenden Problemreduktionsschritte sollen einem funktionalen Programm zu Grunde liegen. Verallgeinere diese Reduktionsschritte zu einem Programm und teste es mit mehreren Funktionsaufrufen. kapital(0) -> 1000 kapital(5) -> kapital(4) + 0.05 * kapital(4)
- Folie 34
- 34 Aufgaben Aufgabe: Ein Patient nimmt jeden Morgen 5 mg eines Medikaments ein. Im Laufe des Tages werden von dem gesamten, im Krper befindlichen Medikament 40% abgebaut. Die Funktion medikamentenmenge(n) beschreibe die Menge des Medikaments (in mg), die sich am n-ten Tag morgens nach Einnahme des Medikaments im Krper befindet. Ergnze die folgenden Problemreduktionsschritte und verallgemeinere sie zu einem funktionalen Programm. medikamentenmenge(0) ->... medikamentenmenge(5) ->...
- Folie 35
- 35 Aufgaben Aufgabe: Was leistet die folgendermaen definierte Funktion? Teste diese Funktion mit verschiedenen Aufrufen und erklre, wie die Ergebnisse zustande kommen. def anzahl(element, liste): if len(liste) == 0: return 0 else: if liste[0] == element: return (1 + anzahl(element, liste[1:])) else: return anzahl(element, liste[1:])
- Folie 36
- 36 Aufgaben Aufgabe: Das Problem besteht darin, ein Element aus einer Liste zu entfernen. Kommt das Element mehrfach vor, so soll nur das erste / alle vorkommende Element entfernt werden. Die folgenden Problemreduktionsschritte sollen den funktionalen Programmen zu Grunde liegen. entferneErstes('b', []) -> [] entferneErstes('b', ['b', 'c', 'b']) -> ['c', 'b'] entferneErstes('b', ['a', 'd', 'b', 'c', 'b']) -> ['a'] + entferneErstes('b', ['d', 'b', 'c', 'b']) entferneAlle('b', []) -> entferneAlle('b', ['b', 'c', 'b']) -> entferneAlle('b', ['a', 'd', 'b', 'c', 'b']) ->
- Folie 37
- 37 Aufgaben Aufgabe: Das Problem besteht darin, jedes Element aus einer Zahleniste um einen bestimmten Wert zu erhhen. Ergnze die folgenden Problemreduktionsschritte und verallgemeinere sie zu einem funktionalen Programm. addiere(3, []) -> addiere(3, [4, 6, 6, 2, 0, 3]) ->
- Folie 38
- 38 Aufgaben Aufgabe: Das Problem besteht darin, aus einer Zahlenliste alle Elemente herauszufiltern, die kleiner als ein bestimmter Wert sind. Erstelle erst einmal geeignete Problemreduktionsschritte. Verallgemeinere sie anschlieend zu einem funktionalen Programm.
- Folie 39
- 39 Teil 3 Funktionen als Datenobjekte
- Folie 40
- 40 Datenstze sortieren Im Sportverein werden die Daten der Mitglieder mit einem Programm verwaltet. Fr jedes Mitglied liegt ein Datensatz vor, der z.B. Vorname, Nachname, Geburtsdatum etc. enthlt. Programme zur Verwaltung solcher Daten bieten in der Regel eine Sortierfunktion an. Mit Hilfe der Sortierfunktion knnen die Daten fr bestimmte Zwecke umsortiert werden, z.B. nach Name und Vorname oder nach dem Geburtsdatum.
- Folie 41
- 41 Datenstze sortieren Es gibt eine Reihe von Sortierverfahren zur Realisierung der Sortierfunktion. Wir betrachten im Folgenden das Sortieren durch Einfgen. def einfuegen(e, L): if len(L) == 0: return [e] else: if e < L[0]: return [e] + L else: return [L[0]] + einfuegen(e, L[1:]) def sortieren(L): if len(L) == 0: return [] else: return einfuegen(L[0], sortieren(L[1:])) Sortieren durch Einfgen
- Folie 42
- 42 def einfuegen(e, L): if len(L) == 0: return [e] else: if e[1] < L[0][1] or (e[1] == L[0][1] and e[0] < L[0][0]): return [e] + L else: return [L[0]] + einfuegen(e, L[1:]) def sortieren(L): if len(L) == 0: return [] else: return einfuegen(L[0], sortieren(L[1:])) Datenstze sortieren def einfuegen(e, L): if len(L) == 0: return [e] else: if e[1] < L[0][1]: return [e] + L else: return [L[0]] + einfuegen(e, L[1:]) def sortieren(L): if len(L) == 0: return [] else: return einfuegen(L[0], sortieren(L[1:])) personendaten = [ ('Britta', 'Koch', (23,5,1995)), ('Paul', 'Schwarz', (11,11,2003)), ('Silke', 'Schmidt', (13,7,1990)), ('Jennifer', 'Abel', (15,12,1993)), ('Adriana', 'Mller', (21,1,2001)), ('Tobias', 'Klein', (1,3,1997)), ('Philipp', 'Bach', (21,4,1997)), ('Oliver', 'Schmitt', (14,4,1994)), ('Simone', 'Schuster', (20,12,2000)), ('Pia', 'Schwarz', (11,11,2003)), ('Andreas', 'Beyer', (16,3,1988)), ('Alexander', 'Heinrich', (17,3,1999)), ('Maximilian', 'Meyer', (21,6,1986))] Alphabetische Sortierung nach dem Nachnamen Alphabetische Sortierung nach dem Nach- und Vornamen Sortierung nach dem Geburtsdatum?
- Folie 43
- 43 Flexible Vergleiche einfuegen [('Andreas', 'Beyer', (16,3,1988)),...] [ ('Andreas', 'Beyer',...),..., ('Pia', 'Schwarz',...),... ] ('Pia', 'Schwarz', (11,11,2003)) L e kleinerNachname vergleich einfuegen [('Andreas', 'Beyer', (16,3,1988)),...] [ ('Pia', 'Schwarz', (11,11,2003)), ('Andreas', 'Beyer', (16,3,1988)),..., ] ('Pia', 'Schwarz', (11,11,2003)) L e juenger vergleich Die Black-Box-Modellierungen zeigen Situationen, in denen eine Vergleichsoperation an die Funktion bergeben wird. In der oberen Abbildung wird als Vergleichsoperation der Vergleich der Nachnamen bergeben, in der unteren Abbildung ein Vergleich der Geburtsdaten.
- Folie 44
- 44 Ein Parameter fr Vergleichsfunktionen einfuegen [('Andreas', 'Beyer', (16,3,1988)),...] [ ('Andreas', 'Beyer',...),..., ('Pia', 'Schwarz',...),... ] ('Pia', 'Schwarz', (11,11,2003)) L e kleinerNachname vergleich Funktionale Programmierung ermglicht solche Situationen, in denen einer Funktion Daten bergeben werden knnen, die selbst eine Funktion darstellen. def einfuegen(e, L, vergleich): if len(L) == 0: return [e] else: if vergleich(e, L[0]) == True: return [e] + L else: return [L[0]] + einfuegen(e, L[1:], vergleich) def sortieren(L, vergleich): if len(L) == 0: return [] else: return einfuegen(L[0], sortieren(L[1:], vergleich), vergleich)
- Folie 45
- 45 Funktionsaufrufe def einfuegen(e, L, vergleich): if len(L) == 0: return [e] else: if vergleich(e, L[0]) == True: return [e] + L else: return [L[0]] + einfuegen(e, L[1:], vergleich) def sortieren(L, vergleich): if len(L) == 0: return [] else: return einfuegen(L[0], sortieren(L[1:], vergleich), vergleich) # Test personendaten = [ ('Jennifer', 'Abel', (15,12,1993)), ('Philipp', 'Bach', (21,4,1997)), ('Andreas', 'Beyer', (16,3,1988)), ('Alexander', 'Heinrich', (17,3,1999)), ('Tobias', 'Klein', (1,3,1997)), ('Britta', 'Koch', (23,5,1995)), ('Maximilian', 'Meyer', (21,6,1986)), ('Adriana', 'Mller', (21,1,2001)), ('Silke', 'Schmidt', (13,7,1990)), ('Oliver', 'Schmitt', (14,4,1994)), ('Simone', 'Schuster', (20,12,2000)), ('Pia', 'Schwarz', (11,11,2003)), ('Paul', 'Schwarz', (11,11,2003))] # Situation 1 def kleinerAlphabetischNachname(person1, person2): if person1[1] < person2[1]: return True else: return False print(sortieren(personendaten, kleinerAlphabetischNachname)) Aufgabe: Teste selbst die verallgemeinerte Sortierfunktion.
- Folie 46
- 46 Aufgabe # Test personendaten = [...] # Situation 2 def geburtsdatum(person): def tag(datum): def monat(datum): def jahr(datum): return def kleinerDatum(datum1, datum2): def juenger(person1, person2): print(sortieren(personendaten, juenger)) Aufgabe: Die Personendaten sollen nach dem Alter der Personen von jung nach alt sortiert werden. Entwickle passende Funktionen. Du kannst dich an dem Vorschlag orientieren.
- Folie 47
- 47 Funktionen hherer Ordnung Eine Funktion hherer Ordnung ist eine Funktion, die Funktionen als bergabedaten erhlt oder eine Funktion als Rckgabedatum zurckliefert. def rechnen(f, a, b): return f(a, b) def add(a, b): return a + b def sub(a, b): return a - b >>> rechnen(add, 3, 6) 9 >>> rechnen(sub, 5, 2) 3
- Folie 48
- 48 Aufgaben Aufgabe: (a) Kann man die Funktion rechnen auch zur Ausfhrung von Vergleichsoperationen benutzen? Fhre hierzu geeignete Tests durch. (b) Die Funktion anwenden ist folgendermaen definiert. Teste die Funktion anwenden mit verschiedenen konkreten Funktionen. def anwenden(f, a): return f(a)
- Folie 49
- 49 Funktion auf Listenelemente anwenden Im Sportverein steht die Berechnung des jhrlichen Mitgliedsbeitrags an. Zwei Beitragberechnungsmodelle sollen durchgespielt werden. Im ersten Modell ist der Beitrag nur grob gestaffelt: Kinder, Jugendliche und Erwachsene zahlen jeweils einen festen Betrag. Im zweiten Modell ist der Beitrag direkt an das Alter (am Ende des Kalenderjahres) gekoppelt. # Berechnungsmodell 1 def beitraegeBerechnen1(personenListe): if personenListe == []: return [] else: (vorname, name, geburtsdatum) = personenListe[0] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter < 10: beitrag = 20 elif alter < 20: beitrag = 40 else: beitrag = 60 personNeu = (vorname, name, geburtsdatum, beitrag) return [personNeu] + beitraegeBerechnen2(personenListe[1:]) # Anwendung personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] print(beitraegeBerechnen1(personendaten))
- Folie 50
- 50 Funktion auf Listenelemente anwenden Aufgabe (a) Teste erst einmal die beiden Funktionen. Entwickle selbst ein weiteres Berechnungsmodell und die passende Berechnungsfunktion. (b) Vergleiche die Funktionsdefinitionen. Welche Gemeinsamkeiten fallen auf? (c) Siehst du eine Mglichkeit, eine Funktion hherer Ordnung zu benutzen, um die gemeinsame Berechnungsstruktur zu erfassen? # Berechnungsmodell 2 def beitraegeBerechnen2(personenListe): if personenListe == []: return [] else: (vorname, name, geburtsdatum) = personenListe[0] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] beitrag = 3 * alter personNeu = (vorname, name, geburtsdatum, beitrag) return [personNeu] + beitraegeBerechnen1(personenListe[1:]) # Anwendung personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] print(beitraegeBerechnen2(personendaten))
- Folie 51
- 51 Der map-Operator Verarbeitungssituation: Jedes Element einer Liste wird mit der gleichen Vorschrift verarbeitet und durch das verarbeitete Element ersetzt. Wir benutzen den sogenannen map-Operator zur Erfassung dieser Verarbeitungssituation. Beispiele zur Anwendung des map-Operators:
- Folie 52
- 52 Der map-Operator def myMap(liste, f): if liste == []: return [] else: return [f(liste[0])] + myMap(liste[1:], f) personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] def beitragBerechnen1(person): (vorname, name, geburtsdatum) = person aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter < 10: beitrag = 20 elif alter < 20: beitrag = 40 else: beitrag = 60 personNeu = (vorname, name, geburtsdatum, beitrag) return personNeu print(myMap(personendaten, beitragBerechnen1)) def myMap(liste, f): return [f(x) for x in liste]
- Folie 53
- 53 Aufgaben Aufgabe: Benutze den map-Operator, um fr eine Funktion eine Wertetabelle zu erstellen.
- Folie 54
- 54 Listenelemente herausfiltern Die Liste der Datenstze zur Verwaltung der Mitglieder des Sportvereins soll nach verschiedenen Kriterien durchsucht werden: Wer gilt als erwachsen (d.h. ist am Ende des Jahres mindestens 18 Jahre alt)? Wer hat im Februar Geburtstag? Wer hat einen Nachnamen, der mit S beginnt? Es sollen alle Datenstze, die das jeweilige Suchkriterium erfllen, ermittelt werden. def erwachsenHerausfiltern(liste): if liste == []: return [] else: person = liste[0] geburtsdatum = person[2] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter >= 18: return [liste[0]] + erwachsenHerausfiltern(liste[1:]) else: return erwachsenHerausfiltern(liste[1:]) # Test personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] # Anfrage 1 print(erwachsenHerausfiltern(personendaten))
- Folie 55
- 55 Listenelemente herausfiltern Aufgabe (a) Entwickle entsprechende Funktionsdefinitionen, um die Datenstze zu den beiden anderen oben genannten Kriterien herauszufiltern. (b) Beschreibe das Schema, das all diesen Filteroperationen zu Grunde liegt. (c) Siehst du eine Mglichkeit, eine Funktion hherer Ordnung zu benutzen, um das gemeinsame Berechnungsschema zu erfassen? def erwachsenHerausfiltern(liste): if liste == []: return [] else: person = liste[0] geburtsdatum = person[2] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter >= 18: return [liste[0]] + erwachsenHerausfiltern(liste[1:]) else: return erwachsenHerausfiltern(liste[1:]) # Test personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] # Anfrage 1 print(erwachsenHerausfiltern(personendaten))
- Folie 56
- 56 Der filter-Operator Verarbeitungssituation: Elemente einer Liste, die eine bestimmte Bedingung erfllen, werden in einer neuen Liste zusammengestellt. Wir benutzen den sogenannen filter-Operator zur Erfassung dieser Verarbeitungssituation. Beispiele zur Anwendung des filter-Operators:
- Folie 57
- 57 Der filter-Operator def myFilter(liste, f): if liste == []: return [] else: if f(liste[0]): return [liste[0]] + myFilter(liste[1:], f) else: return myFilter(liste[1:], f) personendaten = [('Jennifer', 'Abel', (15,12,1993)),...] def erwachsen(person): geburtsdatum = person[2] aktuellesJahr = 2010 alter = aktuellesJahr - geburtsdatum[2] if alter >= 18: return True else: return False # Anfrage 1 print(myFilter(personendaten, erwachsen)) def myFilter(liste, f): return [x for x in liste if f(x)]
- Folie 58
- 58 Aufgaben Aufgabe: Benutze den filter-Operator, um alle positiven / negativen Zahlen aus einer Zahlenliste herauszufiltern. Aufgabe: Benutze den filter-Operator, um Quicksort geschickt zu implementieren.
- Folie 59
- 59 Teil 4 Deklarative Programmierung
- Folie 60
- 60 Dialog ber Datenverarbeitung I: Hallo! Ich vertrete hier die imperative Programmierung. F: Hallo, und ich vertrete die funktionale Programmierung. I: Neulich hast du behauptet, dass man Programme ohne Variablen und Zuweisungen schreiben kann und dass man keine Schleifen bentigt. F: Das stimmt - zumindest so ungefhr! I: Ich kann mir das immer noch nicht so recht vorstellen. Wie soll das z.B. bei einem ganz einfachen Algorithmus wie dem folgenden funktionieren? F: Umdenken ist die Devise! Der Algorithmus benutzt Befehle, um die Daten zu verarbeiten. Die Daten werden dabei mit Hilfe von Variablen verwaltet. Ich mache das ganz anders. Ich konzipiere eine Funktion, die das Gewnschte leistet, und definiere sie mit Hilfe von Regeln. I: Sehe ich das richtig, dass da auch Variablen vorkommen? F: Ja, aber nur als Parameter, um Daten an die Funktion zu bergeben. Der entscheidende Unterschied ist, dass sie ihre Werte nicht verndern. I: Das ist ja alles schn und gut. Aber, wozu soll das Ganze gut sein? Ich komme mit meiner Methode doch auch zum Ziel. F: Stimmt, wir kommen beide zum Ziel, aber mit ganz unterschiedlichen Methoden. Du benutzt Algorithmen, die letztlich aus Anweisungen bzw. Befehlen bestehen. Diese Befehle richten sich an eine tatschliche oder gedachte Maschine. Bei der Entwicklung von Algorithmen musst du also denken wie eine Maschine. I: Das habe ich zwar noch nie so empfunden, aber eigentlich hast du recht. Und wie denkst du? ALGORITHMUS Summenberechnung: {vorher: n aus N} setze s auf 0 setze i auf 0 SOLANGE i 0 {Fall 2:} n > 0: summe(n)->n+summe(n-1)
- Folie 61 0 {Fall 2:} n > 0: summe(n)->n+summe(n-1)">
- 61 Dialog ber Datenverarbeitung F: Ich entwickle Beschreibungen anstatt Befehle zu erteilen. Ich beschreibe das gewnschte Berechnungsverhalten mit einer Funktion, die den Ausgangsdaten die Zieldaten zuordnet. Anschlieend lege ich mit Hilfe von Regeln die Zuordnung przise fest. I: Das erinnert mich irgendwie an Funktionsdefinitionen in der Mathematik. F: Ja, da macht man das ganz genauso. I: Und warum sollen wir beim Programmieren vorgehen wie Mathematiker? Hat das irgendwelche Vorteile? F: Beim Programmieren macht man leicht Fehler. Gib zu, dass du auch schon mal die Anweisung "erhhe i um 1" vergessen hast. Wenn man funktional programmiert, kann man sich leichter von der Korrektheit der Programme berzeugen. Ich mache mir die Korrektheit von Regeln immer anhand typischer Beispiele klar: I: Ok, das sehe ich ein! Aber, wenn ich mich so umschaue, stelle ich fest, dass fast alle imperativ programmieren wie ich. So richtig durchgesetzt hast du dich noch nicht, oder? F: Viele kennen mich halt nicht - das ist irgendwie schade. Die, die mich kennen, benutzen meinen deklarativen Ansatz beim Entwickeln von Prototypen. Es geht hier darum, schnell ein System zu entwickeln, das korrekt arbeitet bzw. das gewnschte Verhalten zeigt. Es kommt nicht darauf an, das Laufzeitverhalten zu optimieren oder Benutzerfreundlichkeit zu gewhrleisten. I: Kannst du das an einem Beispiel klarmachen? F: Gerne, aber erst im nchsten Abschnitt. FUNKTION summe: {Fall 1:} n == 0: summe(n)->0 {Fall 2:} n > 0: summe(n)->n+summe(n-1)
- Folie 62
- 62 Beschreiben statt Befehlen Imperative Programmierung besteht darin, eine (mehr oder weniger abstrakte) Maschine mit Hilfe von Anweisungen zu steuern. Dabei wird beschrieben, wie die Ergebnisse berechnet werden sollen. Zentrale Bausteine imperativer Programme sind Wertzuweisungen, die i.a. den momentanen Variablenzustand (Speicherzustand) verndern. Imperative Programmierung ist wegen der Mglichkeit, Seiteneffekte zu produzieren, recht fehleranfllig. Deklarative Programmierung besteht darin, den Problemkontext (die Miniwelt) mit gegebenen Mitteln zu beschreiben. Funktionale Programmierung - als eine Form der deklarativen Programmierung - benutzt hierzu Funktionen. Bei der deklarativen Programmierung wird somit beschrieben, was in der Modellwelt gelten soll. Die funktionale Programmierung arbeitet dabei ohne Speichervariablen. Variablen kommen hier nur als Funktionsvariablen zur bergabe von Funktionsargumenten vor. Seiteneffekte sind demnach in der funktionalen Programmierung nicht mglich. Das Verhalten einer Funktion wird vollstndig durch die Funktionsdeklarationen festgelegt. Funktionale Programmierung erfolgt auf einem hheren Abstraktionsniveau. Es ergeben sich dadurch Programme, die krzer, leichter zu durchschauen und weniger fehleranflliger sind. Funktionale Programmierung eignet sich zum Prototyping.
- Folie 63
- 63 Prototyping Bei der Entwicklung neuer Produkte wird zunchst oft ein Prototyp erstellt. Dabei handelt es sich um ein funktionsfhiges Modell, das dem geplanten Produkt in vielen Bereichen entspricht, meist aber auch eine Reihe von Vereinfachungen aufweist. Prototypen werden - insbesondere bei komplexen technischen Systemen - zunchst einmal erstellt, um Erfahrungen mit dem neuen System und seiner Entwicklung zu sammeln. Prototypen kommen entsprechend auch bei der Entwicklung komplexer Software zum Einsatz. Wir skizzieren im Folgenden, wie ein Prototyp zu einem RSA-Kryptosystem mit Hilfe der funktionalen Programmierung erstellt werden kann.
- Folie 64
- 64 Prototyp zu einem Kryptosystem Beim RSA-Verfahren werden natrliche Zahlen mit Hilfe eines (ffentlichen bzw. privaten) Schlssels in neue Zahlen umwandelt. from kryptosystem_rsa import * # Testprogramm n = 116063 e = 4097 d = 51137 oeffentlicherSchluessel = (e, n) privaterSchluessel = (d, n) s0 = 'Kln' print(s0) s1 = verschluesseln(s0, oeffentlicherSchluessel, codierenZeichenketteZahlenliste) print(s1) s2 = entschluesseln(s1, privaterSchluessel, decodierenZahlenlisteZeichenkette) print(s2) >>> Kln [99070, 100824, 50230] Kln Die Funktionen zur Realisierung des Prototyps findet man auf den Seiten von www.inf- schule.de (1.22.4.2).
- Folie 65
- 65 Literaturhinweise [Becker 99] K. Becker: Funktionale Programmierung. Materialien zum Lehrplan Informatik. LMZ 1999. (http://informatikag.bildung-rp.de/html/funktprog.html) [Becker 00] K. Becker: Problemlsen mit dem Computeralgebrasystem Derive - informatisch betrachtet. (http://informatikag.bildung-rp.de/html/derive.html) [Becker 04] K. Becker: Funktionale Programmierung mit Caml. (http://informatik.bildung- rp.de/fileadmin/user_upload/informatik.bildung-rp.de/Weiterbildung/pps/WB- FunktionaleProgrammierungCaml.pps) [Lorenz 12] G. Funktionale Modellierung und Rekursion. Oldenbourg Verlag 2012.