3. Funktionale Programmiersprachen Haskell und F#

Größe: px
Ab Seite anzeigen:

Download "3. Funktionale Programmiersprachen Haskell und F#"

Transkript

1 3. Funktionale Programmiersprachen Haskell und F# Einleitung Was haben die zuletzt behandelten vier Programmiersprachen gemeinsam? Wahrscheinlich fällt einem zu dieser Frage zunächst nicht viel mehr ein, dass es halt Programmiersprachen sind. Zu verschieden erscheinen sie einem, als dass man eine weitergehende Gemeinsamkeit entdecken könnte. Und dennoch gibt es sie: Es sind alles imperative Programmiersprachen! Ein Befehl nach dem anderen wird in festgelegter Reihenfolge abgearbeitet. Gewiss, es gibt die Schleifen und bei schlechter Programmierung auch die Sprungbefehle. Das ändert aber nichts daran, dass die Reihenfolge festgelegt ist. Zum besseren Verständnis sollten Sie sich den Abschnitt Klassifikation nach den Programmierparadigma in Kapitel 2.0 (S.75) nochmals durchlesen. Das imperative Paradigma passt sehr genau zur klassischen Von-Neumann- Architektur für Rechner. Es ist relativ leicht zu verstehen und wird daher besonders von Programmier-Novizen bevorzugt. Der Befehl (aus Delphi) x:= x + 5 ist mathematisch gesehen reiner Unfug! Subtrahieren Sie auf beiden Seiten x, dann bekommt man die Aussage: 0 = 5. So kann es also nicht gemeint sein. In der Tat soll die obige Schreibweise etwas ganz anderes heißen: Der Speicherinhalt von x wird mit 5 addiert und wieder auf den Speicher von x geschrieben. Einen solchen Befehl werden Sie in Haskell oder F# vergeblich suchen. Und das liegt daran, dass Haskell und F# funktionale Programmiersprachen sind. Und funktionale Programmiersprachen ruhen auf einem völlig anderen Programmierparadigma: Programme bestehen hier ausschließlich aus einer Vielzahl von Funktionen, daher der Name. Das Hauptprogramm ist eine Funktion, welche die Eingabedaten als Argument erhält und die Ausgabedaten als seinen Wert zurückliefert. Diese Hauptfunktion verwendet in ihrer Definition üblicherweise weitere Funktionen, die wiederum ihrerseits weitere Funktionen verwenden, und das geht so weiter, bis irgendwann, am Boden der Aufrufhierarchie ankommend, nur noch die Grundfunktionen der Programmiersprache verwendet werden, wie etwa die Addition. (Wikipedia) Alles klar?!? Vermutlich nicht! Man kann Obiges auch etwas ausführlicher darstellen. Das soll in den nächsten Abschnitten versucht werden. 1

2 Ein Grund für Verwirrung ist sicher der Umstand, dass der Begriff Funktion auch in imperativen Programmiersprachen verwendet wird. Nur hat er da eine ganz andere Bedeutung, wie in der Mathematik: Funktionen sind in Delphi, Java etc so etwas wie Unterprogramme oder Prozeduren. In Mathematik ist eine Funktion eine eindeutige Zuordnung von einer Menge in eine andere Menge. Beispielsweise ordnet die Funktion f: x x 2 jedem Element x aus der Definitionsmenge (zum Beispiel den rationalen Zahlen) das Quadrat von x zu. Natürlich ist dies eine Funktion, denn die Zuordnung ist eindeutig ( 5 wird eindeutig 25 zugeordnet). Bei der rein funktionalen Programmierung ist dieser mathematische Funktionsbegriff gemeint! Der Vorteil: Man kann jetzt die sehr umfangreich behandelten Methoden der Mathematik nutzen, da man ja auch die gleiche Funktionsdefinition benutzt. Selbst manche Beweise der Mathematik können der funktionalen Programmiersprache dienlich sein. Wer hätte das gedacht? Programme bestehen dort, vereinfacht ausgedrückt, aus Funktionen, die weitere Funktionen aufrufen. Das bedeutet vor allem, dass Funktionen selbst als Übergabewert (Parameter) dienen können. Sie verhalten sich daher mehr oder weniger wie Datentypen aus der imperativen Programmiersprache. Einige Konsequenzen: Es gibt keine Schleifen! Sie werden durch Rekursionen ersetzt! Es gibt keine Variablen! Sie werden durch Parameter ersetzt! Funktionen selbst sind Werte! Das Resultat einer Funktion hängt nur vom Parameterwert ab! Die Rekursion sollten Sie aus der Mathematik kennen. Wenn Ihnen das Thema nicht mehr präsent sein sollte, hier ein kleines Beispiel (natürlich aus der Informatik): Wie würde man etwa in Delphi einen Programmtext zur Berechnung der Fakultät aufschreiben? Eine Möglichkeit: function TFAnwendung.Fakultaet(wZahl:word):longint; var liprodukt: longint; i : word; begin liprodukt:=1; for i:=1 to wzahl do liprodukt:=liprodukt*i; Fakultaet:=liProdukt; end; Kleine Frage am Rande: Welche Bedeutung hat hier der Begriff function? 2

3 Löst man das Problem mit Hilfe einer Rekursion, so sieht der Quelltext (in Haskell) so aus: fak 0 = 1 fak n = n * fak (n-1) Ist doch beeindruckend, der Unterschied! Und wenn man dann noch bedenkt, dass mit dem Delphiprogramm nur maximal 16! berechnet werden kann, während bei Haskell keine theoretische Grenze für n existiert! Man kann dort problemlos 38456! ausrechnen. Versuchen Sie das mal in C#, Delphi, Java oder PHP zu realisieren!! (Wir werden auf das Beispiel zurückkommen): Aufgabe 1 Realisieren Sie das oben angedeutete Fakultiäts-Programm in einer beliebigen imperativen Programmiersprache. (Delphi ist hier bequem, weil der Quellcode schon fast vollständig ist! Programmordner: FakultaetImperativ ) Man darf jetzt aber nicht glauben, dass imperativen Programmiersprachen die Rekursion fremd ist. Um das nicht zu vergessen, lösen Sie die nächste Aufgabe! Aufgabe 2 Versuchen Sie dies mal das Fakultätsproblem in der von Ihnen oben verwendeten Programmiersprache rekursiv zu lösen! (Programmordner: FakultaetRekursiv) Versuchen Sie es zunächst ohne Hilfe. Wenn Sie nicht weiterkommen, dann hilft ein Blick auf die folgenden Zeilen: function Fakultaet(n: longint):longint; begin if n=0 then Fakultaet:= 1 else Fakultaet:= Fakultaet(n-1)*n; end; Schreiben Sie von Hand die Schritte auf, die der Rechner zum Beispiel bei n = 4 zu durchlaufen hat! Das ist sehr lehrreich und nebenbei die beste Methode, Rekursionen zu verstehen! Übrigens: Funktionale Programmiersprachen, wie LISP, Miranda und Haskell, gehören zur Gruppe der deklarativen Programmiersprachen. LISP gibt es schon seit Ende der 50-er Jahre. Die Sprache wurde besonders in der Forschung der künstlichen Intelligenz verwendet. Heute verwendet sie kaum mehr jemand mehr. 3

4 Haskell Grundlagen Den Name verdankt die Sprache dem Mathematiker Haskell Brooks Curry. Er forschte Anfang der 40-er Jahre des letzten Jahrhunderts auf dem Gebiet der kombinatorischen Logik. Diese Theorie bildet die Grundlage und Voraussetzung für funktionale Programmiersprachen. Curry muss schon sehr bedeutendes geleistet haben, wenn man eine Programmiersprache mit seinem Vornamen bezeichnet! Wenn Sie wissen wollen, womit sich Curry sonst noch beschäftigt hat, so lesen Sie zum Beispiel den gut verständlichen Artikel über Currys Paradox bei Wikipedia: Was Wikipedia sonst noch zur Geschiche von Haskell weiß, lesen Sie hier: Gegen Ende der 1980er Jahre gab es bereits einige funktionale Programmiersprachen, alle mit ihren Vor- und Nachteilen. Um der Wissenschaft eine einheitliche Forschungs- und Entwicklungsbasis bereitzustellen, sollte eine standardisierte und moderne Sprache die funktionale Programmierung vereinheitlichen. Zunächst wollte man dazu Miranda als Ausgangspunkt benutzen; doch deren Entwickler waren daran nicht interessiert. So wurde 1990 Haskell 1.0 veröffentlicht. Die aktuelle Version der Programmiersprache ist eine überarbeitete Variante des Haskell-98-Standards von Haskell ist die funktionale Sprache, an der zur Zeit am meisten geforscht wird. Demzufolge sind die Sprachderivate zahlreich; dazu zählen Parallel Haskell, Distributed Haskell und sogar objektorientierte Varianten (Haskell++, O'Haskell, Mondrian). Des Weiteren diente Haskell beim Entwurf neuer Programmiersprachen als Vorlage. So wurde z.b. im Falle von Python die Lambda- Notation sowie Listenverarbeitungssyntax übernommen. ( ) Wenn Sie jetzt noch wüssten, was die Lambda-Notation ist... In Haskell sieht sie so aus: plus a b = a + b Das bedeutet: plus ist eine Funktion (allgemein Lambda genannt), die auf a und b angewandt wird. Das Ergebnis der Funktion ist a + b. So einfach ist das!! Frage: Woher bekommt man eigentlich die Programmiersprache Haskell? Antwort: Wir verwenden hier den Haskell-Interpreter Hugs: 4

5 Das Programm ist Freeware und kann auch vom Tauschverzeichnis auf den USB- Stick geladen werden. Klicken Sie im NAL unter Informatik das Ikon für Haskell doppelt, so sehen Sie dieses Fenster: Hier wurde allerdings bereits, dem Vorschlag am Prompt entsprochen, :? einzugeben. Daraufhin bekommt man einige Kommandos gezeigt. Ein wenig enttäuscht sind Sie schon, stimmts?! Soll das magere Editierfeld alles sein? Warten Sie es ab! Öffnen Sie mit file / Modulmanager das folgende Fenster: 5

6 Offensichtlich gibt es hier bereits geladene Module, die bereits jetzt eine Fülle von Funktionen besitzten. Um dies genauer zu untersuchen, öffnen Sie einen der Module mit dem Button Edit auf der linken Seite. Die Einträge sollte man aber keinesfalls verändern... Wir wollen jetzt in einem ersten Schritt Haskell unsere eigene Addition von oben beibringen (plus a b = a+b) Öffnen Sie mit dem einfachen Windows-Editor ein neues Dokument und schreiben Sie lediglich obige Zeile. Danach speichern Sie das Dokument unter addition.hs ab. Mit dem obigen Modulmanger können Sie danach Ihr erstes Modul laden (add) und danach im Hauptfenster auch benutzen (siehe Bild links). Interessant wäre jetzt zu wissen, was Haskell mit plus a b anfängt. Problieren Sie weitere Möglichkeiten aus! Die erste Programmzeile, die wir geschrieben haben (plus a b = a+b) ist für den Interpreter eine echte Herausforderung. Es wird nämlich nicht festgelegt, welchen Typs die Parameter a und b sein sollen. Und wenn man ein Charakteristikum von Haskell nennen müsste, dann ist es mit Sicherheit die gnadenlose Typenkontrolle! Diesbezüglich ist Haskell das genaue Gegenteil von PHP! Machen wir es also richtig: --plus eigen (Keine Großbuchstaben!!) plus :: Double->Double->Double plus a b = a + b Man kann hier auch erkennen, wie ein Kommentar geschrieben werden kann. 6

7 Die zweite Zeile entspricht der Schreibweise des Lambda-Kalküls. Jetzt allerdings muss man bei der Eingabe des Parameters auch korrekt vorgehen. Dabei geht die Zeile plus noch in Ordnung. Damit aber auch alles klar ist bekommt das Ergebnis einen Dezimalpunkt und eine Null spendiert! Die Funktion plus_i unterscheidet sich von der Funktion plus nur dadurch, dass statt Double Integer verwendet wurde. Daher muss die nebenstehende zweite Rechnung zu einer Fehlermeldung führen. Auch wenn formal 44.0 mit etwas gutem Willen als Integer durchgehen kann. Integer (nicht zu verwechseln mit Int) scheint ein ganz besonderer Datentyp zu sein. Sehen Sie sich die unten abgebildete Ganzzahl-Addition etwas genauer an: Der zweite Summand hat 47 Dezimalstellen. Versuchen Sie es ruhig mal mit 200 oder 300 Stellen... Zeit für einige wichtige Informationen In Haskell muss man zwischen Groß- und Kleinschreibung unterscheiden! Also plus ist nicht gleich Plus!! Wenn man nicht weiß, welchen Typ eine Funktion hat, dann kann man dies mit :t ganz einfach herausbekommen. Zum Beispiel: Das geht natürlich auch mit in Hugs vordefinierten Funktionen: Im Gegensatz zu den ersten Beispielen ist hier kein Parameter-Typ vorgeschrieben. const ist also offensichtlich eine Funktion, die auf zwei beliebige Paramter wirkt und ein Ergebnis vom ersten Typ liefert! Probieren Sie das gleich mal aus. Z.B.: Alles klar? Wenn man eine Funktion definieren will, muss man nicht immer über den Umweg des Skriptes (mit Endung.hs) gehen. Man kann auch eine nur für eine 7

8 Zeile gültige Funktion schreiben: Der Backslash \ steht für Lambda! Bevor Sie nun selbst eigene Kurzzeitfunktionen erstellen, sehen Sie sich diese Zeilen links noch an: Einmal geht s einmal nicht! Weshalb? Will man die Kurzzeitfunktion weiterverwenden, so schreibt man sie wieder in ein Skript (Endung.hs), das man mit dem Modulmanager einliest. Aber Achtung: Das hätten Sie nicht vermutet, stimmt s!? Der Interpreter geht davon aus - wird ihm nichts anderes mitgeteilt - dass es sich bei den Parametern x und y um Integer handelt. Sehr streng, dieser Haskell-Interpreter!! Aufgabe 3 Schreiben Sie als Festfunktion : Eine eigene Quadratfunktion quadrat Die Identitätsfunktion identitaet für beliebige Parameter (Das ist die Funktion, die jedem Wert den selben Wert zuordnet) Eine Funktion nimm2von2, die von zwei eingegebenen Parametern den zweiten Wert zuordnet, - und zwar für beliebige Parameter. Nun muss man ja nicht unbedingt die Funktionen, die in Haskell schon vorhanden sind, erneut programmieren. Daher hier eine Zusammenstellung arithmetischer 8

9 und logischer Operatoren und zudem einige höchst praktischer arithmetischen Funktionen, die durch das Modul Prelude automatisch geladen werden: + Addition = 5 - Subtraktion 2-3 = -1 * Multiplikation 2 * 3 = 6 / Division 2 / 3 = ^ Potenz 2^3 = 8 div ; mod (ganzzahlige Division bzw. Restbildung): div :: Integral a => a -> a -> a mod :: Integral a => a -> a -> a z.b.: (Achtung: div und mod stehen zwischen zwei Accents graves!) gcd ; lmc (größter gem.teiler bzw. kleinstes gem. Vielfaches): gcd :: Integral a => a -> a -> a lcm :: Integral a => a -> a -> a z.b.: even ; odd (gerade bzw. ungerade Zahl): even :: Integral a => a -> Bool odd :: Integral a => a -> Bool z.b.: (Erläuterung: DieTypklasse Integral besteht aus den Typen Int und Integer.) && logisches UND 2<3 && 3<4 = True logisches ODER True False = True not logische Verneinung not (pi<3) = True Wenn Sie die obigen Definitionen aufmerksam gelesen haben, ist Ihnen sicher die Schreibweise even :: Integral a => a -> Bool aufgefallen. Was bedeutet Integral a =>? Haskell unterscheidet drei verschiedene Arten von Funktionen: 9

10 Monomorphe Funktionen, die nur genau einen Eingabetyp akzeptieren: plus :: Double->Double->Double plus a b = a + b Polymorphe Funkionen, die beliebige Eingabetypen akzeptieren: nimm1von2 :: a -> b -> a nimm1von2 a b = a Überladene Funktionen, die mehrere Eingabetypen akzeptieren: quadrat :: Num a => a -> a quadrat a = a*a Die Funktion quadrat lässt sich natürlich nur dann überladen, wenn die Operation auf der erlaubten Klasse, hier Num, definiert ist. Wenn man versucht, die Quadratfunktion polymorph zu definieren, wird man unweigerlich eine Fehlermeldung bekommen: quadratf :: a -> a quadratf a = a*a ERROR.Inferred type is not general enough Rekursion Haskell ist eine funktionale Programmiersprache. Daher gibt es keine Schleifen, sondern Rekursionen, wie wir weiter oben festgestellt haben. In Aufgabe 2 wurde ohne mit Delphi dargestellt, wie man beispielsweise die Berechnung von n! rekursiv bewältigen kann. Auf Seite 162 steht der Programmcode für Haskell. Mit einer Kommentarzeile und und der Festlegung des Definitionsbereichs sieht es nun so aus: -- Definition Fakultät fak :: Integer -> Integer fak 0 = 1 fak n = n * fak (n-1) Einfacher geht nicht! Testen Sie die Programmzeilen! Was ist 8872!? Und jetzt probieren Sie das mal mit Ihrem GTR... In Klasse 12 werden Sie von der Fibonacci-Folge gehört haben oder hören. Und das steckt dahinter: Fibonacci illustrierte diese Folge durch die einfache mathematischen Modellierung des Wachstums einer Kaninchenpopulation nach folgender Vorschrift: 10

11 1. Zu Beginn gibt es ein Paar geschlechtsreifer Kaninchen. 2. Jedes neugeborene Paar wird im zweiten Lebensmonat geschlechtsreif. 3. Jedes geschlechtsreife Paar wirft pro Monat ein weiteres Paar. 4. Die Tiere befinden sich in einem abgeschlossenen Raum ( in quodam loco, qui erat undique pariete circundatus ), so dass kein Tier die Population verlassen und keines von außen hinzukommen kann. Das erste Paar erzeugt seinen Nachwuchs bereits im ersten Monat. Jeden Folgemonat kommt dann zu der Anzahl der Paare, die im letzten Monat gelebt haben, eine Anzahl von neugeborenen Paaren hinzu, die gleich der Anzahl der Paare ist, die bereits im vorletzten Monat gelebt haben, da genau diese geschlechtsreif sind und sich nun vermehren. Fibonacci führte den Sachverhalt für die zwölf Monate eines Jahres vor (1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377) und weist auf die Bildung der Reihe durch Addition mit dem jeweils vorhergehenden Reihenglied hin (1+2=3, 2+3=5, 3+5=8, etc.). Er merkte außerdem an, dass die Folge sich unter der Annahme unsterblicher Kaninchen unendlich fortsetzen lässt: et sic posses facere per ordinem de infinitis numeris mensibus. Weitere Beachtung hatte er dem Prinzip in seinen erhaltenen Werken nicht geschenkt. (Wikipedia ) Zwei ganz andere Zugänge zu der Fibonacci-Folge finden Sie hier: (Fibonacci) Mathematisch ausgedrückt ist der Sachverhalt klarer: f(1) = 1; -- im ersten und zweiten Monat gibt es ein Paar f(2) = 1 f(n) = f(n - 1) + f(n - 2) für n > 2 ; Das obige Verfahren, bei dem vom Interpreter zur Laufzeit zunächst einige Sonderfälle und dann ein allgemeiner Fall geprüft werden, nennt man Patternmatching. Das Ganze erinnert Sie vielleicht entfernt an die if-then-else- Abfragen. Und so falsch liegen Sie da auch nicht. Wie dort kann man hier sehr leicht in eine Endlosschleife einsteiten! Aufgabe 4 Schreiben Sie ein Haskell-Programm, das fib(n), also die Anzahl der Paare nach n Monaten berechnet. Wieviele Paare gibt es nach 23 Monaten? (Keine viel höheren Werte verwenden, wenn Sie nicht Stunden oder Tage warten wollen...) 11

12 Sehr lange braucht das Programm für n = 34. fib(34) = Eine guter Benchmark für Ihren Prozessor!! Das geht entschieden zu langsam! Nicht weil Haskell nichts taugt, sondern weil der Programmcode zwar einfach zu schreiben, aber höchst anspruchsvoll für Prozessor und RAM ist. Das geht viel, viel besser und schneller, wenn man erst einmal Listen in Haskell behandelt hat. Guards (Wächter) Auch wenn mit Pattern-matching unterschiedliche Reaktionen des Programms erreicht werden können, so kann es die if-then-else-konstruktion nicht ersetzten. Diese gibt es zwar auch in Haskell (und wird, wie es sich gehört als Funktion aufgefasst), sind allerdings in funktionalen Programmiersprachen nur zweite Wahl. Denn es gibt etwas viel besseres: die Guards. Diese Wächter werden durch senkrechte Striche eingeleitet und stehen alle untereinander. Ein End-Wächter wird durch otherwise aufgerufen. Ein Beispiel: funktionspezial n n == 1 = 5 -- Wächter 1 mod n 2 == 0 = 7 -- Wächter 2 otherwise = Wächter 3 Erklärung: Wenn n =1, dann wird 5 ausgebeben; ist n durch 2 teilbar, so wird 7 ausgegeben. In allen anderen Fällen bekommt man den Wert 10. Hier die wichtigsten Vergleichsoperatoren: == gleich "Eis" == "eis" = False /= ungleich 2 /= 3 = True < kleiner "Haus" < "haus" = True <= kleiner oder gleich 4 <= sqrt 16 = True > größer 'a' > 'A' = True >= größer oder gleich 3^2 >= 0 = True Aufgabe 5 Wenn Sie nicht mehr wissen, wie die Schaltjahre berechnet werden, so sehen lesen Sie sich die Erklärung in Wikipedia durch: Ist die Jahreszahl durch 4 teilbar, aber nicht durch 100, dann ist es ein Schaltjahr mit 366 Tagen. Beispiele: 1980, 1972,

13 Ist die Jahreszahl durch 100 teilbar, aber nicht durch 400, dann ist das Jahr ein gewöhnliches Gemeinjahr und hat nur 365 Tage, z. B. in den Jahren 1700, 1800 und 1900 oder ferner Ist die Jahreszahl durch 400 teilbar, ist das Jahr ein Schaltjahr. Die Jahre 1600 und 2000 waren in Übereinstimmung mit der Julianischen Schaltregel Schaltjahre zu 366 Tagen. Versuchen Sie nun mit dieser Definition den Programmcode zur Entscheidung, ob ein Jahr y ein Schaltjahr ist oder nicht, zu verstehen: -- Bestimmung Schaltjahr schaltjahr :: Int -> Bool -- (1) schaltjahr y -- (2) mod y 100 == 0 = (mod y 400 == 0) -- (3) otherwise = (mod y 4 == 0) -- (4) Listen Wen wundert es, wenn funktionale Programmiersprachen ihren Hang zur Rekursion auch auf die Datenstrukturen selbst beziehen wollen? Das beste Beispiel für solche rekursiv definierten Datenstrukturen sind die Listen. In Haskell sieht das so aus: [] -- leere Liste [element] -- Liste mit einem Element (x:xs) -- nicht leere Liste, x ist erstes Element, xs ist die Restliste In Listen sind alle nur denbaren Datentypen als Elemente zugelassen, aber alle Elemente müssen den selben Typ haben. Die meisten Listenfunktionen sind polymorph, d.h., sie funktionieren mit allen Listen und sind nicht an einen Typ gebunden. Hier einige Beispiele: [4,6,7,9] :: [Int] ['H','a','l','l','o'] = "Hallo" ["Lehrer","sind","auch", Menschen! ] :: [[Char]] (oder :: [String] ) (1>5):[True, False] = [False, True, False] 5^2 : 6^2 : 3^2 : 1^2 : [ ] = [25, 36, 9, 1] Es gibt auch einige Vereinbarungen bezüglich der Vereinfachung der Schreibweise: [ ] = [20, 21, 22, 23, 24, 25] [ ] = [20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5] [2, ] = [2,4,6,8,10,12] [5, 4.. 1] = [5, 4, 3, 2, 1] 13

14 [5.1, ] = [5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0] [5.1+i*0.1 i<-[0..9]] = [5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0] (die obige Schreibweise erinnert zwar sehr an eine Schleife, ist aber, wie jede Liste in Haskell, durch eine Rekursion entstanden. Siehe Erklärung weiter unten) [1.. ] = [1, 2, 3, 4, 5, 6, ] --unendliche Liste Wie nicht anders zu erwarten, werden Listen rekursiv aus aus Elementen eines Haskell-Typs a aufgebaut. Dazu braucht man zwei Festlegungen: Die leere Liste [] ist eine Liste vom Typ [a] (Induktionsanfang) Ist x ein Element vom Typ a und xs eine Liste vom Typ [a], dann ist x:xs eine Liste vom Typ [a] Durch diese Festlegung (Definition) wird offensichtlich, dass Listen rekursiv konstruiert werden. Das ist alles ziemlich abstrakt. Daher ein Beispiel: 1, 3 und 5 sind Int-Variablen. Weshalb ist dann nach obiger Definition [1,3,5] eine Liste (von Ints)? [1,3,5] = 1 : [3,5] Somit ist [1,3,5] eine Liste, wenn [3,5] eine Liste ist [3,5] = 3 : [5] [3,5] ist eine Liste, wenn [5] eine Liste ist [5] = 5 : [] [5] ist eine Liste, weil [] eine Liste ist. [5.1+i*0.1 i<-[0..9]] = *0.1 : [5.1+1*0.01 : [.]] Und nun liest man die drei Zeilen von unten nach oben und man kommt zum Schluss, dass auch die Anfangsliste [1,3,5] eine Liste sein muss. Der Aufbau unserer Liste ist daher [1,3,5] = 1 : (3 : (5 : [])) oder kurz: [1,3,5] = 1 : 3 : 5 : [] Benutzt man die zweite Schreibweise, so muss einem klar sein, dass eigentlich von rechts aus geklammert sein müsste und man aus Gründen der Bequemlichkeit diese Klammern weggelassen hat. (Mitunter lässt man auch [] noch weg obwohl die leere Liste ja grundlegend für die Konstruktion einer Liste ist). Zeichnerisch veranschaulicht sieht eine Liste daher so aus: Auch Funktionen, die Listen verarbeiten, sind oft nach dem gleichen rekursiven Muster aufgebaut. Ein Beispiel ist die unten dargestellte Funktion anwenden, die auf jedes Element einer Liste eine Funktion f anwendet. (Haskell hat eine solche Funktion natürlich schon implementiert. Sie heißt map). anwenden:: (a -> b) -> [a] -> [b] anwenden f [] = [] -- (Induktionsanfang) 14

15 anwenden f (x:xs) = (f x): anwenden f xs -- (Induktionsschluss) In Zeile Induktionsanfang wird die leere Liste durch Musteranpassung abgefangen (Stoppfall der Rekursion, in Mathematik gerne Induktionsanfang genannt). In Zeile Induktionsschluss wird die Funktion f auf das erste Element der Liste angewandt und danach das Ergebnis mit einem rekursiven Aufruf der Restliste angefügt. Die Funktion anwenden kann auf beliebige Listen losgelassen werden. Zu beachten ist nur, dass die Parameter zusammenpassen: Das erste Argument muss eine Funktion sein, die eine Liste vom Typ des zweiten Parameters (Typ a) erwartet und als Ergebnis eine Liste mit Elementen vom Typ b zurückliefert. Solche universellen Funktionen nennt man polymorph. Beispiele: Main> anwenden sin [0,pi/2,pi] [0.0,1.0,0.0] Main> anwenden toupper "Hallo" "HALLO" Ahnen Sie nun, welches Potenzial in dieser Technik stecken? Angenommen, Sie wollen mal auf die Schnelle das Produkt der natürlichen Zahlen von 1 bis 200 berechenen. Dann sieht das in Haskell so aus: Hugs> product [1..200] (Nein, Sie müssen das Ergebnis nicht aussprechen...) Aufgabe 6 Versuchen Sie durch Erfragen des Typs ( z.b. : t sum ) und durch einfaches Testen, die Wirkungsweise der folgenden Funktionen für Listen zu verstehen: sum, product, maximum, reverse, length, (++), head, tail, drop, take, init, last Mit Listen ist es sehr einfach, Funktions-Tabellen zu erstellen. --Tabelle für die Funktion f von a bis b mit 20 Schritten tabelle20 ::(Float -> Float) -> Float -> Float -> [Float] tabelle20 f a b = [f(x) x<-[a, a+(b-a)/20.. b]] Mit dem Ergebnis: Main> tabelle20 quadrat

16 [0.0,0.01,0.04,0.09,0.16,0.25,0.36, , , ,1.0,1.21,1.44, , , , , , , , ] (Wenn Ihnen die Genaugikeit nicht ausreicht, verwenden Sie Double statt Float) Um die Anzahl der Schritte variabel zu halten, muss nur wenig geändert werden: --Tabelle für die Funktion f von a bis b mit n Schritten tabelle ::(Float -> Float) -> Float -> Float -> Float -> [Float] tabelle f a b n = [f(a+i*(b-a)/n) i<-[0..n]] Schauen Sie sich genau an, wie man erreicht hat, dass n+1 Funktionswerte (zwischen a und b mit Abstand (b-a)/n) in die Liste geschrieben werden! Und jetzt ein kleiner Test des neuen Codes: Eine Tabelle für die Sinusfunktion zwischen 0 und 3 in 100 Schritten ist gewünscht: Main> tabelle (\x->sin x) [0.0, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] Damit kann man natürlich auch noch mehr anfangen: Zum Beispiel das Integral einer stetigen Funktion f näherungsweise mit der Unter- bzw Untersummenregel berechenen. (Siehe Bild rechts für die Obersumme gezeichnet) Die Fläche unter dem Schaubild von a bis b bekommt man danach (ungefähr), wenn man br*f(a+1*br) + br*f(a+2*br)...+br*f(b) mit br = (b-a)/n 16

17 zusammenzählt. Im Bild sind das die fünf gelben Rechtecke. Hier ist das Ergebnis mit n = 5 natürlich noch sehr schlecht. Wie kann man es besser machen? Und nun der Programmcode hierzu in Haskell: --Integral-Näherung flaeche :: (Double -> Double) -> Double -> Double -> Double -> Double flaeche f a b n= br*sum [f(a+i*br) i<-[1..n]] where br = (b-a) /n Wem die Schreibweise der Liste mit i<-[1..n] suspekt ist, wählt diese Lösung: flaeche2 :: (Double -> Double) -> Double -> Double -> Double -> Double flaeche2 f a b n = br*sum (map f [a,a+br..b]) where br = (b-a) /n Ein Beispiel dazu (a=0, b=4, n=10000): Main> flaeche (\x->x^3) Mit einer Million Abschnitte bekommt man bereits Der exakte Wert ist 64 (= 1/4* 4 4 für alle, die die Integralrechnung schon beherrschen!) Erinnern Sie sich an das Sieb des Eratosthenes? Ein besonders wirkungsvoller Algorithmus zur Primzahlberechnung mit einem leider sehr hohen Speicherbedarf! Lesen Sie dazu hier nach: Und so sieht der Zweizeiler dazu in Haskell aus: primzahlen = sieb [2..] where sieb (x:xs) = x:sieb [y y <- xs, y `mod` x /= 0] Rekursion und unendliche Liste! So einfach kann ein Programm sein. Wer will, kann ja mal versuchen, das Programm in Visual C#, Delphi, Java oderphp zu programmmieren... (Achtung: Infix-Operatoren also solche, die nicht vor den Variablen sondern zwischen ihnen stehen wie mod, muss man in accents graves einschließen!) Aufgabe 7 Ändern Sie die obige Definition so ab, dass die Primzahlen bis zu einer bestimmten Zahl ausgegeben werden: primzahlen_bis :: Integral a => a -> [a] Formulieren Sie zunächst eine Definition für einen Primzahltest: istprim :: Integral a => a -> Bool (Tipp: Es gibt kein n in [1..x] für das x mod n = 0) Schreiben Sie damit eine Definition zur Bestimmung von Primzahlzwillingen bis m. 17

18 Tupel Listen sind in Haskell ein ganz wesentliches Element. Erst mit ihnen wird eine funktionale Programmiersprache erst konkurenzfähig. Dennoch sind auch Listen nicht immer das passende Mittel. Ein Beispiel: Eine mp3-datei enthält in der Regel nicht nur die Musik sondern auch sogenannte Tags in denen Informationen zu dieser Datei gespeichert sein können. Ein Tupel, das dem obigen Beispiel gerecht wird, könnte die Form (String, String, String, String, Int, Int, String) haben. Das erste Tupel wäre dann: ("La Vie en Rose", "Edit Piaf", "Edit Piaf", "World Of Disc 1", 1, 2002) Der WinHugs- Editor stellt leider nur Tupel mit maximal fünf Elementen dar. Rechnen kann man aber mit deutlich längeren Tupeln. Eine Funktion, die das zweite Element, also den Interpret, aus dem Tag ausliest, kann man so definieren: --zweites Element von sechs interpret :: (a,b,c,d,e,f) -> b interpret (a,b,c,d,e,f) = b Mit dem Aufruf: Main> interpret ("La Vie en Rose", "Edit Piaf", "Edit Piaf", "World Of Disc 1", 1, 2002) "Edit Piaf" Wer seine gesamte Musiksammlung getaggt hat, besitzt also eine Liste aus Tupeln. Mit der map-und der interpret-funktion kann man sich dann beispielsweise alle Interpreten der Sammlung auslesen lassen. In der Praxis haben die meisten Haskell-Tupel zwei (Paare) oder drei (Trippel) Elemente. Für Paare gibt es zwei Standardfunktionen: Main> fst ('a','b') 'a' Main> snd (3,4) 4 Beachten Sie, dass man diese beiden Funktionen nur auf Tupel mit zwei Elementen anwenden kann. Ein Anwendungsbeispiel aus der Mathematik ist das Skalarprodukt im dreidimensionalen Raum. ( ) In Haskell lässt sich es so darstellen: skalarprodukt :: (Float, Float, Float) -> (Float, Float, Float) -> Float skalarprodukt (x1,x2,x3) (y1,y2,y3) = x1*y1+x2*y2+x3*y3 Mit dem Aufruf: Main> skalarprodukt (4.5,2.7,6.3) (9.2,4.8,2.6)

19 Aufgabe 8 Definieren Sie eine Funktion tausch2, die die zwei Werte eines Paares vertauscht. Schreiben Sie eine Funktion abstand2, die den Abstand zweier Punkte 2 2 P(x1,y1) und Q(x2,y2) in der Ebene berechnet. ( d = ( x2 x1) + ( y2 y1) ) Auch im 3-dimensionalen Raum kann man den Abstand zweier Punkte P(x1,y1,z1) und Q(x2,y2,z2) berechnen. Schreiben Sie hierfür die Funktion abstand3. ( d = ( x2 x1) + ( y2 y1) + ( z2 z1) ) Es soll der Abstand zweier Städte, deren Geodaten (Längengrad, Breitengrad) bekannt sind, errechnet werden. Die Formel: abstandlb = acos[ sin(breite1)*sin(breite2) + cos(breite1)*cos(breite2)*cos(laenge2-laenge1) ] * erdradius Dabei ist erdradius = 6371 km. acos ist die Umkehrfunktion des Cosinus. Beachten Sie: breite1, laenge1 etc. müssen in Bogenmaß eingegeben werden: l1 (im Bogenmaß)= laenge1*pi/180 etc. Zürich hat die Geokoordinaten (Länge,Breite) (8.54 Grad, Grad). Los Angeles liegt auf ( Grad, Grad). Wieviel km beträgt der kürzeste Abstand? Mit GoogleEarth können Sie sich übrigens die Geodaten jedes beliebigen Ortes beschaffen. Da diese aber in Grad, Minuten und Sekunden angegeben werden, müssen sie erst in Dezimalzahlen umgewandelt werden. Beispiel: ,44 = / ,44/3600 = 47, Hier ein einfaches Beispiel, wie man mit einer Liste von Tupeln umgehen kann: Sind mehrere nummerierte Punkte einer Ebene gegeben, so kann man einen Streckenzug von Punkt 1 zu Punkt 2 etc. und schließlich bis zum Endpunkt festlegen. 19

20 Die Liste könnte so aussehen: punktl = [(1.0,1.2), (0.3, -2.4), (-3.9, 4.7), (6.7,2.9)] Eine Liste ( laengenl2 )mit den Abständen zwischen den einzelnen Punkten wäre hilfreich, die Funktion gesamtlaenge2 zu definieren. Für das obige Beispiel: laengenl = [ , , ] und hat damit ein Element weniger als die ursprüngliche Liste aus Paaren. laengenl2 :: [(Double,Double)] -> [Double] laengenl2 [ ] = [ ] laengenl2 (x : [ ]) = [ ] -- nur ein Punkt ergibt keine Länge! laengenl2 (p1 : p2 : restpunkte) = (abstand2 p1 p2) : (laengenl2(p2 : restpunkte)) Ein kurzer Test der Hilfsfunktion zeigt, dass wir auf dem richtigen Weg sind. Die Streckenlängen zwischen den Punkten müssen nun noch aufaddiert werden. Zwar gibt es mit sum eine passende Listenfunktion in Haskell wir werden, der Übung halber diese Funktion selbst schreiben: summe :: Num a => [a] -> a summe [ ] = 0 summe (x : xs) = x + (summe xs) Aufgabe 9 Definieren Sie mit den neuen Hilfsfunktionen die gesuchte Funktion gesamtlaenge2. Zeigen Sie, dass die Gesamtlänge im obigen Beispiel beträgt. Definieren Sie eine Funktion gesamtlaenge3, die die Länge eines Streckenzuges im dreidimensionalen Raum berechnet. Verwenden Sie als Beispiel die Punkteliste: [(2.3,7.4,9.2),(3.4,6.9,-3.2),(-3.0,4.2,-2.8),(6.7,3.1,1.2)] Currying und uncyrrying Bisher waren unsere Funktionen so aufgebaut, dass man einen Wert nach dem anderen ohne Klammer hinter die Funktion schrieb. Beispiel: plus 5 7. Dies nennt man nach Haskell Curry currying. Das hat, wie wir später noch genauer sehen werden, den Vorteil, dass man auch partielle Funktionen erzeugen kann. Etwas plus5 = plus 5. Andererseits ist es mit Hilfe der Tupel jetzt auch möglich, der Funktion alle Werte auf einmal zu übergeben (uncurrying). In unserem Beipiel könnte man ein Paar-Plus so definieren: plusp :: (Float, Float) -> Float plusp (x,y) = x + y Zwischen diesen beiden Funktionen kann man beliebig hin- und her springen: curry addierep 3 5 Oder auch anders herum: uncurry addiere (3,5) Testen Sie das Currying und das Uncurrying! 20

21 Funktionen für Listen Sobald man einige Zeit mit Listen gearbeitet hat, merkt man, dass es praktisch wäre, wenn man Funktionen zur Verfügung hat, die etwas Listen-typisches können, wie zusammenfügen, ordnen, einfügen oder entfernen. Beginnen wir daher mit einer Aufgabe Aufgabe 9 Schreibe einen Programmcode für eine Funktion: entfernenint :: Integer -> [Integer] -> [Integer] Beispiel : Main> entfernenint 3[1,2,3,4,5] [1,2,4,5] Schreibe den obigen Programmcode um,so dass entferne ein überladene Funktion wird. Beachten Sie, dass ein Vergleich für die Elemente vorgenommen werden muss. Die Klasse, aus der die Elemente genommen werden können, ist also mindestens Eq. Erzeuge eine Funktion zusammen, die zwei gleichartige Listen zu einer Liste zusammenfügt. Beispiel: Main> zusammen [2,4,6] [1,3,5] [2,4,6,1,3,5] Die wichtigsten Funktionen, die auf Listen wirken, sind polymorph oder wenigstens überladen. Im ersten Fall kann man sie für alle Listen verwenden, im zweiten Fall auf eine ganze Gruppe, wie zum Beispiel Listen, die aus Zahlen bestehen (Num). Die oben selbst gebastelte Funktion zusammen, ist polymorph. Sie ist in Haskell bereits vordefiniert durch ++ Main> [2,4,6] ++ [1,3,5] [2,4,6,1,3,5] Etwas anderes ist es, zwei bereits geordnete Listen zu einer geordenten Liste zusammenzufügen. Machen Sie sich an einem einfachen Beispiel, wie etwa [1, 3, 5] und [2, 4, 6] klar, dass folgender Programmcode diesen Zweck erfüllt: merge [] ys = ys merge (x:xs)[] = x:xs --Induktionsanfang merge (x:xs) (y:ys) x <= y = x:merge xs (y:ys) x > y = y:merge (x:xs) ys Main> merge [1,3,5] [2,4,6] [1,2,3,4,5,6] Erstes Zwischenergebnis: 1 : merge [3, 5] [2, 4, 6] Zweites Zwischenergebnis: 1 : 2 : merge [3, 5] [4, 6] 21

22 Wie geht es weiter? Problem: Wie kann man eine Funktion merge_ordnung auf zwei ungeordneten Listen definieren, die die beiden in eine geordnete Liste zusammenfügt? Also z.b.: merge_ordnung [3, 2] [9, 1] = [1, 2, 3, 9] Zunächst ist klar, dass man die beiden Listen nur einzeln ordnen muss. Denn dann kann man die obige Funktion merge darauf anwenden. Wir brauchen also eine Funktion sortiere :: Ord a => [a] -> [a], also: sortiere [4, 1, 6] = [1, 4, 6] sortiere Hierfür werden wir das sogenannte Sortierverfahren insertion-sort verwenden. Die Idee ist sehr einfach: Zunächst benötigt man eine passend_einsetzen Funktion. Sie soll ein einzelnes Element korrekt in eine schon geordnete Liste einfügen. Zum Beispiel: passend_einsetzen 4 [2, 6] = [2, 4, 6] Dann setzt man jedes einzelne Element der ungeordneten Liste durch die Funktion nach_rechts in eine neue, diesesmal aber automatisch geordnete Liste ein. Die neue Liste ist zunächst leer. Ein Beispiel: sortiere [4, 1, 6] = nach_rechts [4, 1, 6] [ ] = nach_rechts [1, 6] (passend_einsetzen 4 [ ]) = nach_rechts [1, 6] [4] = nach_rechts [6] (passend_einsetzen 1 [4]) =? Zunächst also erstellen wir eine Funktion für passend_einsetzen. Polymorph können wir die Funktion nicht gestalten, da Relationen, wie größer oder kleiner möglich sein müssen. Die größtmögliche passende Klasse wäre Ord. Eingabe sind ein Ord- Element und eine Ord-Liste. Ausgabe ebenfalls eine Ord-Liste: passend_einsetzen :: Ord a => a -> [a] -> [a] Nun noch die Festlegung, wie passend_einsetzen auf eine leere Liste und wie auf eine gefüllte wirken muss: passend_einsetzen y [ ] = [y] passend_einsetzen y (x:xs) -- x : xs ist schon geordnet y<x = y:x:xs -- y ist kleinstes Element otherwise = x: (passend_einsetzen y xs) -- x ist kleinstes Element Es fehlt noch die Festlegung für nach_rechts. Zwei Listen werden eingegeben und eine Liste wird ausgegeben: nach_rechts :: Ord a => [a] -> [a] -> [a] Am Ende ist die Rekursion, wenn es aus der linken Liste nichts mehr in die rechte Liste (=gliste für geordnete Liste ) eingefügt werden kann, weil erstere leer ist. nach_rechts [ ] gliste = gliste Ist die linke Liste nicht leer, so wird ihr erstes Element in die geordnete_liste passend eingesetzt: 22

23 nach_rechts (x:xs) gliste = nach_rechts xs (passen_einsetzen x gliste) Aufgabe 9 Versuchen Sie mit Hilfe des obigen Beispiels die Rekursion zu verstehen. Testen Sie nach_rechts z.b. durch Main> nach_rechts [3,6,1] [2,5] [1,2,3,5,6] Versuchen Sie nun die Funktion sortiere mit Hilfe von nach_rechts zu erstellen! (Tipp: Bringen Sie die ungeordnete Liste nach_rechts in eine zunächst leere Liste!) merge_ordnung Das Ziel war, zwei ungeordnete Listen durch eine Funktion namens merge_ordnung in einer geordneten Liste zu vereinigen. Da wir bereits die Funktion nach_rechts haben, die lediglich davon ausgeht, dass die rechte Liste bereits geordnet ist, müssen wir daher nur mit sortiere dafür sorgen, dass die rechte Liste auch geordnet ist: --Zwei ungeordnete Listen in einer geordneten Liste vereinigen merge_ordnung :: Ord a => [a] -> [a] -> [a] merge_ordnung liste1 liste2 = nach_rechts liste1 (sortiere liste2) elementnummer Die Listen in Haskell sind mit Null beginnend indiziert. Das bedeutet, dass man sich zum Beispiel das dritte Element einer Liste ausgeben lassen kann: Main> [2,3,4,5,6]!! 2 4 Zur Übung schreiben wir einen solchen Indexzugriff selbst. Der Aufruf soll so aussehen: elementnummer [2,4,6,8] 1 (= 4) So kann man ihn erzeugen: --indexzugriff eigen elementnummer :: [a]->int->a elementnummer (x:xs) 0 = x elementnummer (x:xs) (n+1) = elementnummer xs n 23

24 map-, filter- und fold-studien Die map-funktion ist vermutlich die wichtigste aller Listen-Funktionen. Wir haben sie oben bereits selbst als anwenden Funktion definiert. Zur Erinnerung: anwenden:: (a -> b) -> [a] -> [b] anwenden f [] = [] -- (Induktionsanfang) anwenden f (x:xs) = (f x): anwenden f xs -- (Induktionsschluss) Im Folgenden können Sie also immer wenn die Funktion map verwendet wird, ebenso gut die Funktion anwenden nutzen, sofern Sie sie importiert haben. Als weiteres Beispiel für die map- Funktion werden wir die Caesar-Verschlüsselung programmieren. Hier wird jeder Buchstabe um einen bestimmten Wert n im Alphabeth verschoben. Für n = 3 würde beispielsweise aus C -> F und aus Z -> C. Wir wollen, wie in der Kryptologie üblich, nur Großbuchstaben ohne Umlaute verwenden. Diese Art der Verschlüsselung ist zugegebenermaßen nicht ernst zu nehmen. Hat man die Technik im Umgang mit Character aber einmal verstanden, so sind anspruchsvollere Verschlüsselungen kein Problem mehr. WinHugs muss den Umgang mit ASCII-Tabellen erst beigebracht werden. Dazu benutzen Sie das Modul Char.hs im Verzeichnis C:\Programme\WinHugs\packages\hugsbase\Hugs Am besten kopieren Sie alles aus dieser Datei bis auf die zu ladenden Module, die ja schon geladen sind, in Ihre neue Datei namens caeser.hs. Nach dem Laden zeigt Ihnen der Befehl Hugs.Char> ord 'A' 65 dass der Buchstabe A durch 65 im ASCII-Code festgelegt ist. Will man zu einem ASCII-Code das zugehörige Zeichen wissen, so schreibt man: Hugs.Char> chr 90 'Z' Will man die Großbuchstaben von A bis Z bei Null beginnend durchnummeriert haben, so bietet sich folgende Funktion an: stelle :: Char -> Int stelle zeichen = (ord zeichen) -65 Und die Umkehrung: buchstabe :: Int -> Char buchstabe stelle = chr ( stelle + 65) Jetzt kann man durch Eingabe der Stelle des Zeichens und des Schlüssels n die neue Position des verschlüsselten Buchstabens errechen: verschiebe :: Int -> Int -> Int verschiebe n stelle = mod (stelle + n) 26 24

25 Nimmt man alles zusammen, so lässt sich eine Funktion caesar auf Character definieren: caesar :: Int -> Char -> Char caesar n zeichen = buchstabe (verschiebe n (stelle zeichen)) In der Mathematik würde die caesar n Funktion als Verkettung geschrieben: caesar n (zeichen) = (buchstabe(verschiebe n (stelle(zeichen))) = (buchstabe o verschiebe n o stelle) (zeichen) Und genau so wird dies auch in Haskell gemacht, nur der Verknüpfungszeichen o wird als einfacher Punkt geschrieben: caesarv :: Int -> Char -> Char caesarv n zeichen = (buchstabe. verschiebe n. stelle) zeichen (Das große V im Namen soll auf Verknüpfung hindeuten.) Und nun kommt map ins Spiel: Main> map (caesar 4) "HALLOALLEMITEINANDER" "LEPPSEPPIQMXIMRERHIV" Der String HALLO. ist eine Liste aus Character. Also kann man mittels map die (caeser 4) Funktion auf alle Character wirken lassen. Bequemer geht es nicht! Aufgabe 10 Definieren Sie eine Funktion caesarstring :: Int -> String -> String, die unter Verwendung eines Schlüssels n einen vorgegebenen String aus Großbuchstaben verschlüsselt. Wie kann man diese Funktion für die Entschlüsselung eines Textes verwenden? Aufgabe 11 Die Funktion caesarstring aus Aufgabe 10 wurde durch die Verknüpfung der drei Funktionen buchstabe, verschiebe n und stelle erzeugt. Natürlich kann man eine derartige Funktion auch in einem Zug definieren. So zum Beispiel: caesartext :: Int -> String -> String caesartext _ [] = [] caesartext n (x:xs) = verschluesselt : caesartext n xs where verschluesselt = chr(65 + mod (ord x n) 26) Versuchen Sie die Wirkungsweise der Funktion caesertext nachzuvollziehen und testen Sie die Definition. Wie kann man den verschlüsselten Text wieder entschlüsseln? (Tipp: Man denkt zunächst daran, den Wert der Verschiebung durch Subtraktion wieder rückgängig zu machen. Das würde aber bedeuten, dass wir eine neue Funktion schreiben müssten. Man kann aber durch eine geeignete Addition ebenfalls erreichen, dass die Verschiebung wieder rückgängig gemacht wird ) 25

26 Wie Sie wissen, ist die Cäsar-Verschlüsselung sehr leicht zu entschlüsseln. Es gibt ja nur 26 Möglichkeiten der Verschiebung. Sehr viel schwerer macht man es dem Angreifer, wenn die Buchstaben der Reihe nach mit verschiedenen Werten verschoben wird. Ein Beispiel: Das Wort HALLO könnte immer abwechselnd um 1 und 2 verschoben werden. Man könnte sich daher eine Funktion caesarvar vorstellen, die man so aufruft: caesarvar [1,2] HALLO "ICMNP" Nach einigen Überlegungen erkennt man jedoch, dass noch ein Akkumulator mit auf den Weg gegeben werden muss, der festhält, wo man gerade in der Liste sich befindet bzw. bei welchem Wert man starten soll. In der Regel dürfte dies Null sein, so dass der Aufruf dann so aussehen würde: caesarvar 0 [1,2] HALLO Die Liste [1,2] bezeichnet man übrigens als Schlüssel, da ohne sie kein öffnen des Geheimtextes möglich ist. (Zugegeben: Bei einem so kurzen Schlüssel kommt man vermutlich auch mit Gewalt brutal force an den Inhalt!) Hier ein Vorschlag für eine solche Funktion: caesarvar :: Int -> [Int] -> String -> String caesarvar n schluessel [ ] = [ ] caesarvar n schluessel (x:xs) (n+1) < length(schluessel) = caesar m x : caesarvar (n+1) schluessel xs (n+1) >= length(schluessel) = caesar m x : caesarvar 0 schluessel xs where m = elementnummer schluessel n Aufgabe 12 Die folgenden beiden Aufgaben sind relativ einfach zu lösen und zeigen dabei eindrucksvoll, welche Möglichkeiten man mit der Funktion map hat: Ein Internetshop verkauft verschiedene Artikel, mit Netto-Preisen von 1, 2, 3,, also immer Cent-freie Beträge. Nun muss der Kunde aber noch 19% Mehrwertsteuer bezahlen, bekommt aber auf den Gesamtbetrag bei Sofort-Zahlung 3% Skonto. Definieren Sie eine dazu passende Funktion endpreis, mit deren Hilfe dann endpreisliste erzeugt werden kann. Anwendung: endpreisliste [ ] soll dann alle möglichen Endpreise erzeugen. Viel besser wäre es, wenn aus der Netto-Preisliste eine Paar-Liste aus Netto- Preis und Endpreis erzeugt würde. Definieren Sie eine passende Funktion listeinpreisendpreisliste :: [Float] -> [(Float, Float)] Tipp: Erzeugen Sie zunächste eine Funktion listeinpaarliste :: [a] -> [(a,a)], dann preisendpreis :: (Float, Float) -> (Float, Float) und schließlich preisendpreisliste :: [(Float, Float)] -> [(Float, Float)]. Anwendungsbeispiel: Main> listeinpreisendpreisliste [1..10] [(1.0,1.1543),(2.0,2.3086),(3.0,3.4629),(4.0,4.6172),(5.0,5.7715),(6.0,6.9258),( 7.0,8.0801),(8.0, ),(9.0, ),(10.0,11.543)] 26

27 Eine Filterfunktion, die rekursiv bestimmte Elemente einer Liste auswählt, ist mit filter in Haskell bereits fest vorgegeben: filter :: (a -> Bool) -> [a] -> [a] Man benötigt offensichtlich eine Bedingung für a und eine Liste. Beispiel zunächst für eine Bedingung: istnegativ :: (Ord a, Num a) => a -> Bool istnegativ zahl = (zahl < 0) Es mag Sie verwundern, dass man zwei Klassen angeben muss, um eine solche Bedingung für alle Zahlen zu definieren. Num reicht nicht, weil in Num auch komplexe Zahlen definiert sind. Für diese gibt es kein kleiner. Ord reicht nicht, weil der Vergleich mit einer Zahl (0) erfolgt. Natürlich könnte man sich das Leben auch einfach machen und (mit Recht) darauf vertrauen, dass bei der Definition istnegativ :: Float -> Bool auch alles gut geht, weil eine Integer (ohne Dezimalpunkt) in Haskell als Float durchgeht Damit kann man eine Filterfunktion für Listen aus Zahlen definieren: nurnegative :: (Ord a, Num a) => [a] -> [a] nurnegative liste = filter istnegativ liste Beispiel: Main> nurnegative [ ] [-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1] Soweit die Vorübung. Die Filterfunktion soll, um die Verschlüsselung von Text später etwas komfortabler zu gestalten, alle Blanks aus einem Text entfernen. In einem zweiten und dritten Schritt werden später dann noch alle Buchstaben in Großbuchstaben verwandelt und danach die Umlaute ersetzt (Ö = OE etc.), so dass man einen gewöhnlich geschriebenen Text in die für die Verschlüsselung korrekte Form bringen kann. Zifffern und Sonderzeichen werden bei dieser Form der Verschlüsselung jedoch nicht berücksichtigt! Die Bedingung: istnichtblank :: Char -> Bool istnichtblank zeichen = (zeichen /= ' ') Die Funktion mit Anwendung: nichtblank :: String -> String nichtblank text = filter istnichtblank text Main> nichtblank "Hallo alle miteinander!" "Halloallemiteinander!" Aufgabe 13 Um einen beliebigen Text für die Standard-Verschlüsselung anzupassen, müssen nicht nur die Blanks entfernt werden. Danach sollte man alle Umlauteund ß umschreiben (Ö = OE etc.) und schließlich die Kleinbuchstaben in Großbuchstaben verwandeln. Damit keine Sonderzeichen oder Ziffern übrig bleiben, muss am Ende noch nach Großbuchstaben gefiltert werden. ( dürfen im Text dennoch nicht verwendet werden!) Ein solche zusammengesetzte Funktion könnte so aussehen: textbereinigen :: String -> String textbereinigen text = filter istgrossbuchstabe ((ingrossbuchstaben. umlauteundscharfsweg. nichtblank) text) Schreiben Sie die passenden Teilfunktionen und die Bedingung istgrossbuchstabe 27

28 Ausgesprochen praktisch sind auch die fold-funktionen foldl und foldr. Eine Anfrage mit :t gibt Auskunft über den Typ der Funktion: Main> :t foldl foldl :: (a -> b -> a) -> a -> [b] -> a (Gilt auch für foldr) fold erwartet als Eingabe eine Relation, einen beliebigen Wert und eine Liste. Zwei einfache Beispiele (Klammern dienen hier Demonstration der Reihenfolge): foldl (+) 0 [1,2,3] = fold (+) (0+1) [2,3] = foldl (+) ((0+1)+2) [3] = foldl (+) (((0+1)+2)+3) [ ] = (((0+1)+2)+3) = 6 foldr (*) 1 [4,5,6] = foldr (*) (1*6) [4,5] = foldr (*) ((1*6)*5) [4] = foldr (*) (((1*6)*5)*4) [ ] = (((1*6)*5)*4) = 120 Die Anfangswerte 0 bzw. 1 dienen hier als Akkumulator. Meist gibt es, abhängig von der Relation, einen Standard-Akkumulator. Mehr dazu unter Partielle Funktionen. Mit diesen Funktionen und mit der bereits erstellten Funktion passend_einsetzen lässt sich eine sehr einfache Sortierfunktion beispielsweise für Float-Werte definieren: floatsort :: [Float] -> [Float] floatsort xs = foldr passend_einsetzen [ ] xs Dass foldl und foldr verschiedene Ergebnisse haben können, erkennt man, wenn man als Relation die üblichen (+) bzw. (*)-Beispiele verlässt. Aufgabe 14 Untersuchen Sie, welche Definition und Wirkung die Relation (:) hat. Mit flip werden die Eingabeparameter vertauscht: (-) 3 4 = -1, während flip (-) 3 4 = 1. Welche Definition und Wirkung hat die Relation (flip (:) )? Definieren Sie nun ein Funktion invertiere :: [a] -> [a], die eine Liste umdreht: Aus [1,2,3] wird [3,2,1]. Tipp: Verwenden Sie die Funktion (flip (:) ) als Relation für foldl. Welchen neutralen Parameter muss man übergeben? Um zum Beispiel das Maximum einer Liste zu suchen, kann man die Funktion foldl1 verwenden. Sie ist definiert durch: foldl1 f (x:xs) = foldl f x xs Das bedeutet, dass foldl1 nicht auf leere Listen wirken kann, denn als zu übergebende Parameter wird einfach das erste Listenelement verwendet. Als Relation bietet sich max :: Int -> Int -> Int an: maximum :: Ord a => [a] -> a maximum liste = foldl1 max liste Wenn Sie maximum auf eine leere Liste anwenden, bekommen Sie daher eine Fehlermeldung. 28

29 Partielle Funktionen Wenn man der Bequemlichkeit halber immer mit Schlüssel n = 5 arbeiten will, so lässt sich eine angepasste Funktion definieren: caesarstring5 :: String -> String caesarstring5 = caesarstring 5 caesarstring erwartet zwei Eingaben, caesarstring5 nur eine! Diese Art der Auswertung der Funktion caesarstring nennt man partiell. Aus einer Funktion f :: Int -> String -> String entsteht die Funktion f n :: String -> String, die dann auch kurz h :: String -> String genannt werden kann. Partielle Funktionen müssen daher die ersten Eingaben (links) der ursprünglichen Funktion bekannt sein. Dadurch entsteht eine neue Funktion, die auf die Eingabe der restlichen Parameter (rechts) wartet. caesarvar in partielle Funktion verwandeln Die obige Funktion caesarvar benötigt immer noch die Eingabe des Akkumulators. Dieser ist aber in aller Regel Null. Deshalb liegt es nahe, die partielle Funktion caesarvariabel :: [Int] -> String -> String caesarvariabel = caesarvar 0 zu definieren. Aufruf und Ergebnis sehen dann so aus: Main> caesarvariabel [3,7,1,9,11,22,4,15,21,5] "WERDENSCHLUESSELNICHTKENNTHATWENIGCHANCEN" "ZLSMPJWRCQXLTBPHRXXMWRFWYPLPOBHUJPNDECXJQ" Aufgabe 15 Ein Schlüssel der Länge 10 angewandt auf einen Text der Länge 41 weshalb ist das ohne Kenntnis des Schlüssels kaum zu dechiffrieren? Weshalb machen im Schlüssel keine Zahlen oberhalb 26 einen Sinn? Im Schlüssel dürfen Zahlen auch mehrfach vorkommen. Ist in diesem Fall die Entschlüsselung einfacher? Was nutzt die beste Verschlüsselung, wenn man den Geheimtext nicht mehr entschlüsseln kann? Wie wir oben (hoffentlich) eingesehen haben, muss man einen Buchstaben, der beispielsweise mit 5 verschoben wurde, ein zweites Mal mit (26 5) = 21 verschieben und man kommt beim alten Buchstaben raus. Das bedeutet, dass man von jede einzelne Ziffer des Schlüssels 26 abziehen muss und dann diesen neuen Schlüssel der Funktion caesarvariabel mitsamt dem Geheimtext vorsetzten muss. Definieren wir hierzu eine Hilfsfunktion 29

30 gegenschluessel :: [Int] -> [Int] gegenschluessel schluessel = map (\x -> 26 - x) schluessel Dann kann man die Entschlüsselungsfunktion so definieren: caesarvariabelentschluesseln schluessel geheimtext = caesarvariabel (gegenschluessel schluessel) geheimtext Das Ganze in der Anwendung: Main> caesarvariabelentschluesseln [3,7,1,9,11,22,4,15,21,5]"ZLSMPJWRCQXLTBPHRXXMWRFWYPLPOBHUJPNDEC XJQ" "WERDENSCHLUESSELNICHTKENNTHATWENIGCHANCEN" Mit der Funktion caesarvariabel und ihrer Umkehrfunktion haben wir ein einfaches aber wirkungsvolles Mittel zur sicheren Verschlüsselung konstruiert. Wirklich sicher darf sich aber nur derjenige fühlen, der einen hinreichend langen Schlüssel verwendet und das ist der Haken an der Sache diesen Schlüssel sicher dem Empfänger übergibt. Man nennt diese Art der Verschlüsselung übrigens polyalphabetisch (im Gegensatz zur Cäsarverschlüsselung, die monoalphabetisch genannt wird). Vigenère (16.Jhrt) hat diese Idee als Erster dokumentiert. Hier finden Sie einige Informationen: Damals wie heute verwendet man als Schlüssel keine Ziffernfolge, wie wir das tun, sondern man verwendet Buchstaben. Der Schlüssel ABBA wäre in unserer Schreibweise dann [1,2,2,1], also A bedeutet Verschiebung um 1,, Z bedeutet Verschiebung um 26. Passen wir unsere Funktionen dementsprechend an. Das Einzige was wir dazu benötigen ist eine Funktion verwandle, die aus einem String- Schlüssel einen Ziffernschlüssel macht: verwandle :: String -> [Int] -- verwandelt String in [Int] mit A = 1, verwandle text = map (\x -> ord x - 64) text Die Funktion vigenere, die statt einer Ziffernfolge einen String-Schlüssel erwartet, kann dann so geschrieben werden: vigenere :: String -> String -> String vigenere schluesselwort text = caesarvariabel (verwandle schluesselwort) text Aufgabe 16 Definieren Sie die zugehörige Entschlüsselungsfunktion vigenereentschluesseln und testen Sie Verschlüsselung und Entschlüsselung an einigen Beispielen. Wie lang sollte ein sinnvoller Schlüssel maximal sein? Kombinieren Sie die Funktion vigenere mit der oben behandelten Funktion textbereinigen, sodass auch beliebige Texte (aber ohne ) eingegeben werden können. 30

31 sortiere als partielle Funktion betrachten Zur Übung werden wir die obige sortiere Funktion als partielle Funktion einer allgemeineren Funktion betrachten. Denn es gibt ja ganz offensichtlich viele Möglichkeiten, eine Liste zu sortieren. Bisher ist sortiere nur auf Listen der Elementen-Klasse Ord (Num und Char) erklärt und es wird von klein nach groß geordnet. Beispiel: Main> sortiere "Unordnung" "Udgnnnoru" (Beachte: ord U = 85 aber ord u = 117) Wir wollen eine Funktion sortierea :: (a -> a -> Bool) -> [a] -> [a] definieren, die als erste Eingabe eine Relation (a -> a -> Bool) auf a erwartet. Hierbei sind der Phantasie keine Grenzen gesetzt. Ein einfaches Beispiel wäre die Relation (>), die zu einer absteigenden Sortierung führen würde. Wenn die Relation gar auf Paaren wirkt, ergeben sich noch viel mehr Möglichkeiten. Ein Beispiel: Die Paare (Hans, Müller), (Gustav, Gans), (Marion, Fink), werden im Allgemeinen nach dem Nachnamen, also hier dem zweiten Eintrag des Paares, geordnet. Zur Erinnerung die bisherige sortieren Funktion mit ihren Hilfsfunktionen: -- Element in geordnete Liste einordnen passend_einsetzen :: Ord a => a -> [a] -> [a] passend_einsetzen y [ ] = [y] passend_einsetzen y (x:xs) -- x : xs ist schon geordnet y<x = y:(x:xs) -- y ist kleinstes Element otherwise = x: (passend_einsetzen y xs) -- x ist kleinstes Element --Hilfsfunktion nach_rechts nach_rechts :: Ord a => [a] -> [a] -> [a] nach_rechts [ ] gliste = gliste nach_rechts (x:xs) gliste = nach_rechts xs (passend_einsetzen x gliste) --insertion sort sortiere :: Ord a => [a] -> [a] sortiere liste = nach_rechts liste [ ] Schreiben wir zunächst die erste Hilfsfunktion um: -- Element in geordnete Liste einordnen allgemeine Relation passend_einsetzena :: (a -> a -> Bool) -> a -> [a] -> [a] passend_einsetzena relation y [ ] = [y] passend_einsetzena relation y (x:xs) -- x : xs ist schon geordnet relation y x = y:(x:xs) -- y ist nach vorgebener Relation vorderes Element otherwise = x: (passend_einsetzena relation y xs) -- x vorderes Element Kurzer Test: Main> passend_einsetzena (>) 5 [7,6,1] [7,6,5,1] 31

32 Fehlt noch die verallgemeinerte Hilfsfunktion --Hilfsfunktion nach_rechtsa nach_rechtsa :: (a -> a -> Bool) -> [a] -> [a] -> [a] nach_rechtsa relation [ ] gliste = gliste nach_rechtsa relation (x:xs) gliste = nach_rechtsa relation xs (passend_einsetzena relation x gliste) Schlussendlich noch die verallgemeinerte Sortierfunktion: sortierea :: (a -> a -> Bool) -> [a] -> [a] sortierea relation liste = nach_rechtsa relation liste [ ] Erneuter Test: Main> sortierea (>) [4,5,6,1,44,42,82,34] [82,44,42,34,6,5,4,1] Die Relation ist kleiner (>) wäre ganz sicher kein Grund, eine verallgemeinerte Sortierfunktion zu schreiben. Der eigentliche Grund sind, wie schon erwähnt, Relationen, die nicht vordefiniert sind wie ist kleiner zwischen zwei Zahlen. Betrachten Sie hierzu eine Liste von 3-er-Tupeln. Erster Eintrag: Vorname, zweiter Eintrag: Nachname, dritter Eintrag: Alter. Beispiel: [( Anton, Maier,53), ( Silke, Born, 21), ( Anja, Dom,44), ( Michael, Hank, 72)] Wer diese Tupel ordnen soll, fragt doch zunächst, nach welchem Kriterium zu ordnen ist, mit anderen Worten, welche Relation zu verwenden ist. Und genau das ist ein Fall für unsere verallgemeinerte Sortierfunktion. Wir wollen die Tupel nach Alter ordnen. Also brauchen wir erst eine passende Relation: istjuenger :: Ord c => (a,b,c) -> (a,b,c) -> Bool istjuenger (x1,y1,z1) (x2,y2,z2) = z1<z2 Die passende Sortierfunktion: sortierenachalter :: Ord c => [(a,b,c)] -> [(a,b,c)] sortierenachalter = sortierea istjuenger Mit fold lassen sich viele Operationen auf Listen anwenden. Ein Beispiel: Sie wollen die logische Operation or auf eine boolsche Liste [true, false,true,false] anwenden. Wenn wir die Liste von links nach rechts lesen wollen, dann wäre dies eine Lösung, die foldl als partielle Funktion nutzt: or = foldl ( ) False Aufgabe 17 Schreiben Sie nun eine Funktion für die obigen Tupel, die nach Nachnamen sortiert. Tipp: Zuerst die Relation kleinernachname definieren! Drücken Sie die logische Operationen and mit foldl aus. Ergibt die Kombination mit foldr das gleiche Ergebnis? 32

33 In Aufgabe 4 haben wir uns mit der Fibonacci-Folge beschäftigt. Es war zwar nicht weiter schwierig, das Problem rekursiv zu lösen, - die Ausführungsgeschwindigkeit war allerdings mehr als bescheiden. Mit Listen geht es viel, viel schneller: fibschnell :: [Integer] fibschnell = 0 : 1 : (zipwith (+) fibschnell (tail fibschnell)) Wie Sie oben schon selbst herausgefunden haben entfernt tail das erste Element einer Liste. Neu ist für uns zipwith: Hier werden zwei Listen elementweise mit einer bestimmten Funktion ( hier (+) ) verknüpft. Zum Beispiel die Verknüpfung mit (*): Main> zipwith (*)[1, 4, 6] [7, 8, 9] [7,32,54] Der obige Programmcode für die Fibonacci- Folge ist eine Konstruktionsvorschrift : 0 : 1 : (zipwith (+) [0,1,f1,f2,f3..] [1,f1,f2,f3..]) Man erkennt sofort, dass f1 =1 sein muss. Daraus ergibt sich dann f2 etc. Hier noch ein gut gemeinter Rat: Positionieren Sie die Maus direkt über dem kleinen Quadrat für Stop program execution bevor Sie die Enter-Taste drücken. Denn es darf nicht viel Zeit vergehen zwischen Programmstart und Stopp. Sehen Sie selbst, weshalb das so ist! Bei fast gleichzeitigem Drücken von Keybordund Maustaste ist die letzte Fibonacci-Zahl vor dem Interrupt : Sind Sie schneller? (Es ist schon eine beachtliche Leistung, wenn man die ersten Fibonacci-Zahlen noch auf der Liste hat. Denn wegen der maximal zulässigen Anzahl von Zeichen auf dem Editor, wird immer wieder von vorn her gelöscht. Nach bereits recht kurzer Zeit stoppt der Prozess, denn dann ist der Papierkorb voll! Die ganze Liste fünfzehn eng beschriebene Seiten- liegt im Tauschverzeichnis: FibonacciZahlen.doc ) Das obige Konstrukt nennt man übrigens eine unendliche Liste! Unendlich ist sie natürlich nur theoretisch... Auch das ist eine unendliche Liste: quadrate = [n*n n <- [0..]] Testen Sie diese und andere derartige Listen! 33

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell): Was bisher geschah deklarative Programmierung funktional: Programm: Menge von Termgleichungen, Term Auswertung: Pattern matsching, Termumformungen logisch: Programm: Menge von Regeln (Horn-Formeln), Formel

Mehr

Autor: Michael Spahn Version: 1.0 1/10 Vertraulichkeit: öffentlich Status: Final Metaways Infosystems GmbH

Autor: Michael Spahn Version: 1.0 1/10 Vertraulichkeit: öffentlich Status: Final Metaways Infosystems GmbH Java Einleitung - Handout Kurzbeschreibung: Eine kleine Einführung in die Programmierung mit Java. Dokument: Autor: Michael Spahn Version 1.0 Status: Final Datum: 23.10.2012 Vertraulichkeit: öffentlich

Mehr

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = 0.51129 Euro ergeben.

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = 0.51129 Euro ergeben. Aufgabe 1.30 : Schreibe ein Programm DM_in_Euro.java zur Umrechnung eines DM-Betrags in Euro unter Verwendung einer Konstanten für den Umrechnungsfaktor. Das Programm soll den DM-Betrag als Parameter verarbeiten.

Mehr

3 Berechnungen und Variablen

3 Berechnungen und Variablen 3 Berechnungen und Variablen Du hast Python installiert und weißt, wie man die Python-Shell startet. Jetzt kannst Du etwas damit machen. Wir fangen mit ein paar einfachen Berechnungen an und wenden uns

Mehr

Java Einführung Operatoren Kapitel 2 und 3

Java Einführung Operatoren Kapitel 2 und 3 Java Einführung Operatoren Kapitel 2 und 3 Inhalt dieser Einheit Operatoren (unär, binär, ternär) Rangfolge der Operatoren Zuweisungsoperatoren Vergleichsoperatoren Logische Operatoren 2 Operatoren Abhängig

Mehr

Eine Baumstruktur sei folgendermaßen definiert. Eine Baumstruktur mit Grundtyp Element ist entweder

Eine Baumstruktur sei folgendermaßen definiert. Eine Baumstruktur mit Grundtyp Element ist entweder Programmieren in PASCAL Bäume 1 1. Baumstrukturen Eine Baumstruktur sei folgendermaßen definiert. Eine Baumstruktur mit Grundtyp Element ist entweder 1. die leere Struktur oder 2. ein Knoten vom Typ Element

Mehr

PIWIN 1 Übung Blatt 5

PIWIN 1 Übung Blatt 5 Fakultät für Informatik Wintersemester 2008 André Gronemeier, LS 2, OH 14 Raum 307, andre.gronemeier@cs.uni-dortmund.de PIWIN 1 Übung Blatt 5 Ausgabedatum: 19.12.2008 Übungen: 12.1.2009-22.1.2009 Abgabe:

Mehr

Grundlagen Programmierung

Grundlagen Programmierung 1. Aufgabe (Spielen mit Objekten) Gegeben sei der auch von der Veranstaltungsseite erhältliche Programmcode auf der rechten Seite, der im Detail zuerst nicht verstanden werden muss. a) Erzeugen Sie sich

Mehr

Numerische Datentypen. Simon Weidmann

Numerische Datentypen. Simon Weidmann Numerische Datentypen Simon Weidmann 08.05.2014 1 Ganzzahlige Typen 1.1 Generelles Bei Datentypen muss man immer zwei elementare Eigenschaften unterscheiden: Zuerst gibt es den Wertebereich, zweitens die

Mehr

Arbeiten mit Arrays. 4.1 Eigenschaften. 4.1.1 Schlüssel und Element. Kapitel 4

Arbeiten mit Arrays. 4.1 Eigenschaften. 4.1.1 Schlüssel und Element. Kapitel 4 Arbeiten mit s Eine effiziente Programmierung mit PHP ohne seine s ist kaum vorstellbar. Diese Datenstruktur muss man verstanden haben, sonst brauchen wir mit weitergehenden Programmiertechniken wie der

Mehr

Funktionale Programmierung

Funktionale Programmierung Schleifen 1 Funktionale Programmierung Jörg Kreiker Uni Kassel und SMA Solar Technology AG Wintersemester 2011/2012 3 Teil I Jedem Anfang wohnt ein Zauber inne 4 Über mich Diplom in Informatik in Saarbrücken

Mehr

Übungspaket 19 Programmieren eigener Funktionen

Übungspaket 19 Programmieren eigener Funktionen Übungspaket 19 Programmieren eigener Funktionen Übungsziele: Skript: 1. Implementierung und Kodierung eigener Funktionen 2. Rekapitulation des Stack-Frames 3. Parameterübergabe mittels Stack und Stack-Frame

Mehr

Verträge für die funktionale Programmierung Design und Implementierung

Verträge für die funktionale Programmierung Design und Implementierung 1 Verträge für die funktionale Programmierung Design und Implementierung RALF HINZE Institut für Informatik III, Universität Bonn Römerstraße 164, 53117 Bonn, Germany Email: ralf@informatik.uni-bonn.de

Mehr

Sructred Query Language

Sructred Query Language Sructred Query Language Michael Dienert 11. November 2010 Inhaltsverzeichnis 1 Ein kurzer Versionsüberblick 1 2 SQL-1 mit einigen Erweiterungen aus SQL-92 2 3 Eine Sprache zur Beschreibung anderer Sprachen

Mehr

Gibt es verschiedene Arten unendlich? Dieter Wolke

Gibt es verschiedene Arten unendlich? Dieter Wolke Gibt es verschiedene Arten unendlich? Dieter Wolke 1 Zuerst zum Gebrauch des Wortes unendlich Es wird in der Mathematik in zwei unterschiedlichen Bedeutungen benutzt Erstens im Zusammenhang mit Funktionen

Mehr

Arbeiten mit BlueJ. Objektorientiertes Programmieren in Java mit BlueJ

Arbeiten mit BlueJ. Objektorientiertes Programmieren in Java mit BlueJ Arbeiten mit BlueJ Compilieren, Editieren, Objekte erzeugen, Methoden aufrufen, Objekte inspizieren, vorhandene Klassen benutzen, eigene Klassen und Methoden erstellen In BlueJ geht es einfach BlueJ durch

Mehr

Einführung in PHP. (mit Aufgaben)

Einführung in PHP. (mit Aufgaben) Einführung in PHP (mit Aufgaben) Dynamische Inhalte mit PHP? 2 Aus der Wikipedia (verkürzt): PHP wird auf etwa 244 Millionen Websites eingesetzt (Stand: Januar 2013) und wird auf etwa 80 % aller Websites

Mehr

Objektorientiertes Programmieren für Ingenieure

Objektorientiertes Programmieren für Ingenieure Uwe Probst Objektorientiertes Programmieren für Ingenieure Anwendungen und Beispiele in C++ 18 2 Von C zu C++ 2.2.2 Referenzen und Funktionen Referenzen als Funktionsparameter Liefert eine Funktion einen

Mehr

Noch für heute: primitive Datentypen in JAVA. Primitive Datentypen. Pseudocode. Dezimal-, Binär- und Hexadezimalsystem. der logische Typ boolean

Noch für heute: primitive Datentypen in JAVA. Primitive Datentypen. Pseudocode. Dezimal-, Binär- und Hexadezimalsystem. der logische Typ boolean 01.11.05 1 Noch für heute: 01.11.05 3 primitie Datentypen in JAVA Primitie Datentypen Pseudocode Name Speichergröße Wertgrenzen boolean 1 Byte false true char 2 Byte 0 65535 byte 1 Byte 128 127 short 2

Mehr

Vorlesung. Funktionen/Abbildungen 1

Vorlesung. Funktionen/Abbildungen 1 Vorlesung Funktionen/Abbildungen 1 1 Grundlagen Hinweis: In dieser Vorlesung werden Funktionen und Abbildungen synonym verwendet. In der Schule wird eine Funktion häufig als eindeutige Zuordnung definiert.

Mehr

2: Zahlentheorie / Restklassen 2.1: Modulare Arithmetik

2: Zahlentheorie / Restklassen 2.1: Modulare Arithmetik Stefan Lucks Diskrete Strukturen (WS 2009/10) 57 2: Zahlentheorie / Restklassen 2.1: Modulare Arithmetik Uhr: Stunden mod 24, Minuten mod 60, Sekunden mod 60,... Rechnerarithmetik: mod 2 w, w {8, 16, 32,

Mehr

Zur Vereinfachung betrachten wir nun nur noch Funktionen f, die einen Funktionswert f nµberechnen. Sie werden alle in einer Tabelle dargestellt:

Zur Vereinfachung betrachten wir nun nur noch Funktionen f, die einen Funktionswert f nµberechnen. Sie werden alle in einer Tabelle dargestellt: Informatik 13: Gierhardt Theoretische Informatik III Berechenbarkeit Nicht-berechenbare Funktionen Nach der Church-Turing-These kann alles, was berechenbar ist, mit einer Turing-Maschine oder einer While-Maschine

Mehr

Primitive Datentypen

Primitive Datentypen Primitive Datentypen 2 Arten von Datentypen: primitive Datentypen (heute) Objekte (später) Java ist streng typisiert, d.h. für jede Variable muß angegeben werden was für eine Art von Wert sie aufnimmt.

Mehr

Programmierkurs: Delphi: Einstieg

Programmierkurs: Delphi: Einstieg Seite 1 von 6 Programmierkurs: Delphi: Einstieg Aus Wikibooks Inhaltsverzeichnis 1 Einstieg Einstieg Was ist Delphi Borland Delphi ist eine RAD-Programmierumgebung von Borland. Sie basiert auf der Programmiersprache

Mehr

Kurzeinführung in C++

Kurzeinführung in C++ Kurzeinführung in C++ Johannes J. Schneider 27.10.2004 1 Einleitung C++ ist eine heutzutage in vielen Bereichen sehr häufig verwendete Programmiersprache, die auf der Programmiersprache C aufsetzt, aber

Mehr

Klausur in Programmieren

Klausur in Programmieren Studiengang Sensorik/Sensorsystemtechnik Note / normierte Punkte Klausur in Programmieren Winter 2009/2010, 18. Februar 2010 Dauer: 1,5h Hilfsmittel: Keine (Wörterbücher sind auf Nachfrage erlaubt) Name:

Mehr

Folge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Folge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12 Grundlagen: Folge 19 - Bäume 19.1 Binärbäume - Allgemeines Unter Bäumen versteht man in der Informatik Datenstrukturen, bei denen jedes Element mindestens zwei Nachfolger hat. Bereits in der Folge 17 haben

Mehr

Übung 9. Quellcode Strukturieren Rekursive Datenstrukturen Uebung 9

Übung 9. Quellcode Strukturieren Rekursive Datenstrukturen Uebung 9 Informatik I 2 Übung 9 Quellcode Strukturieren Rekursive Datenstrukturen Uebung 9 Quellcode Strukturieren Wenn alle Funktionen in einer Datei zusammengefasst sind wird es schnell unübersichtlich Mehrere

Mehr

Repräsentation von Daten Binärcodierung von rationalen Zahlen und Zeichen

Repräsentation von Daten Binärcodierung von rationalen Zahlen und Zeichen Kapitel 4: Repräsentation von Daten Binärcodierung von rationalen Zahlen und Zeichen Einführung in die Informatik Wintersemester 2007/08 Prof. Bernhard Jung Übersicht Codierung von rationalen Zahlen Konvertierung

Mehr

Zum Einsatz von Operatoren im Informatikunterricht

Zum Einsatz von Operatoren im Informatikunterricht Friedrich-Schiller-Universität Jena Fakultät für Mathematik und Informatik Professur für Didaktik der Informatik/Mathematik Claudia Strödter E-Mail: claudia.stroedter@uni-jena.de Zum Einsatz von Operatoren

Mehr

Ausarbeitung des Interpreter Referats

Ausarbeitung des Interpreter Referats Ausarbeitung des Interpreter Referats Gliederung 1. Programmiersprache 1.2. Syntax 1.2.1. Konkrete Syntax 1.2.2. Abstrakter Syntax Baum (Abstrakte Syntax) 2. Parser 2.1. Syntaktische Struktur einer Sprache

Mehr

Lua - Erste Schritte in der Programmierung

Lua - Erste Schritte in der Programmierung Lua - Erste Schritte in der Programmierung Knut Lickert 7. März 2007 Dieser Text zeigt einige einfache Lua-Anweisungen und welchen Effekt sie haben. Weitere Informationen oder eine aktuelle Version dieses

Mehr

WS 2011/2012. Georg Sauthoff 1. November 10, 2011

WS 2011/2012. Georg Sauthoff 1. November 10, 2011 in in WS 2011/2012 Georg 1 AG Praktische Informatik November 10, 2011 1 gsauthof@techfak.uni-bielefeld.de Kontakt in Dr. Georg Email: gsauthof@techfak.uni-bielefeld.de M3-128 in Organisation der Übungen

Mehr

Programmieren was ist das genau?

Programmieren was ist das genau? Programmieren was ist das genau? Programmieren heisst Computerprogramme herstellen (von griechisch programma für Vorschrift). Ein Computerprogramm ist Teil der Software eines Computers. Als Software bezeichnet

Mehr

Spezifikation der zulässigen Parameter. Bemerkungen: Bemerkungen: (2) Design by Contract:

Spezifikation der zulässigen Parameter. Bemerkungen: Bemerkungen: (2) Design by Contract: Spezifikation der zulässigen Parameter Bemerkungen: Bei jeder (partiellen) Funktion muss man sich überlegen und dokumentieren, welche aktuellen Parameter bei einer Anwendung zulässig sein sollen. Der Anwender

Mehr

Kapitel 7 des Buches, von Java-Selbstbau nach Scala-Library portiert. 2014-11-14 Christoph Knabe

Kapitel 7 des Buches, von Java-Selbstbau nach Scala-Library portiert. 2014-11-14 Christoph Knabe Anfragen für Listen Kapitel 7 des Buches, von Java-Selbstbau nach Scala-Library portiert. 2014-11-14 Christoph Knabe 1 MapReduce-Verfahren Google u.a. verwenden Map-Reduce-Verfahren zur Verarbeitung riesiger

Mehr

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny Grundlagen der Informatik Prof. Dr. Stefan Enderle NTA Isny 2 Datenstrukturen 2.1 Einführung Syntax: Definition einer formalen Grammatik, um Regeln einer formalen Sprache (Programmiersprache) festzulegen.

Mehr

Teilbarkeit von natürlichen Zahlen

Teilbarkeit von natürlichen Zahlen Teilbarkeit von natürlichen Zahlen Teilbarkeitsregeln: Die Teilbarkeitsregeln beruhen alle darauf, dass man von einer Zahl einen grossen Teil wegschneiden kann, von dem man weiss, dass er sicher durch

Mehr

ax 2 + bx + c = 0, (4.1)

ax 2 + bx + c = 0, (4.1) Kapitel 4 Komplexe Zahlen Wenn wir uns auf die reellen Zahlen beschränken, ist die Operation des Wurzelziehens (also die Umkehrung der Potenzierung) nicht immer möglich. Zum Beispiel können wir nicht die

Mehr

Funktionale Programmierung. ALP I Lambda-Kalkül. Teil IVb WS 2012/2013. Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

Funktionale Programmierung. ALP I Lambda-Kalkül. Teil IVb WS 2012/2013. Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda ALP I Lambda-Kalkül Teil IVb WS 2012/2013 λ-kalkül-parser Hilfsfunktionen: Die break-funktion ist eine Funktion höherer Ordnung, die eine Liste beim ersten Vorkommen einer Bedingung in zwei Listen spaltet.

Mehr

Kapiteltests zum Leitprogramm Binäre Suchbäume

Kapiteltests zum Leitprogramm Binäre Suchbäume Kapiteltests zum Leitprogramm Binäre Suchbäume Björn Steffen Timur Erdag überarbeitet von Christina Class Binäre Suchbäume Kapiteltests für das ETH-Leitprogramm Adressaten und Institutionen Das Leitprogramm

Mehr

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung Übersicht 3.1 Modell Konto 3.2 Modell Konto - Erläuterungen 3.3 Benutzer Ein- und Ausgabe mit Dialogfenster I 3.4 Benutzer Ein- und Ausgabe mit Dialogfenster II 3.5 Klassen- und Objekteigenschaften des

Mehr

Aufgaben des MSG-Zirkels 10b Schuljahr 2007/2008

Aufgaben des MSG-Zirkels 10b Schuljahr 2007/2008 Aufgaben des MSG-Zirkels 10b Schuljahr 2007/2008 Alexander Bobenko und Ivan Izmestiev Technische Universität Berlin 1 Hausaufgaben vom 12.09.2007 Zahlentheorie 1 Aufgabe 1.1 Berechne die (quadratischen)

Mehr

HEUTE. Effizienzbeispiel: bekannte Version (Übung 04.11.04) Mathematik: Was ist Effizienz? vollständige Induktion

HEUTE. Effizienzbeispiel: bekannte Version (Übung 04.11.04) Mathematik: Was ist Effizienz? vollständige Induktion 17.11.04 1 HEUTE 17.11.04 3 Effizienzbeispiel: bekannte Version (Übung 04.11.04) Mathematik: was ist Effizienz? vollständige Induktion JAVA: Arrays die for -Schleife die Sprunganweisungen break und continue

Mehr

Fragen. f [ ] = [ ] f (x : y : ys) = x y : f ys f (x : xs) = f (x : x : xs) Wozu evaluiert f [1, 2, 3] (Abkürzung für f (1 : 2 : 3 : [ ]))?

Fragen. f [ ] = [ ] f (x : y : ys) = x y : f ys f (x : xs) = f (x : x : xs) Wozu evaluiert f [1, 2, 3] (Abkürzung für f (1 : 2 : 3 : [ ]))? Fragen f [ ] = [ ] f (x : y : ys) = x y : f ys f (x : xs) = f (x : x : xs) Wozu evaluiert f [1, 2, 3] (Abkürzung für f (1 : 2 : 3 : [ ]))? Wozu evaluiert [f [ ], f [ ]]? Weiteres Beispiel: f [ ] y = [

Mehr

Werkstatt Multiplikation Posten: 8-Bit Multiplikation. Informationsblatt für die Lehrkraft. 8-Bit Multiplikation

Werkstatt Multiplikation Posten: 8-Bit Multiplikation. Informationsblatt für die Lehrkraft. 8-Bit Multiplikation Informationsblatt für die Lehrkraft 8-Bit Multiplikation Informationsblatt für die Lehrkraft Thema: Schultyp: Vorkenntnisse: Bearbeitungsdauer: 8-Bit Multiplikation (im Binärsystem) Mittelschule, technische

Mehr

Besprechung des 3. Übungsblattes MIMA-Interpreter MIMA-Aufgabe: Primzahltest Weitere MIMA-Aufgaben online

Besprechung des 3. Übungsblattes MIMA-Interpreter MIMA-Aufgabe: Primzahltest Weitere MIMA-Aufgaben online Themen heute Besprechung des 3. Übungsblattes MIMA-Interpreter MIMA-Aufgabe: Primzahltest Weitere MIMA-Aufgaben online Besprechung des 3. Übungsblattes Aufgabe 3 Speicherplätze für Mikrocode-Anweisungen

Mehr

Die Bedeutung abstrakter Datentypen in der objektorientierten Programmierung. Klaus Kusche, September 2014

Die Bedeutung abstrakter Datentypen in der objektorientierten Programmierung. Klaus Kusche, September 2014 Die Bedeutung abstrakter Datentypen in der objektorientierten Programmierung Klaus Kusche, September 2014 Inhalt Ziel & Voraussetzungen Was sind abstrakte Datentypen? Was kann man damit grundsätzlich?

Mehr

Erster Bug: eine Motte

Erster Bug: eine Motte SOFTWAREFEHLER Der erste Bug Erster Bug: eine Motte Der Begriff Bug (deutsch: Motte) stammt aus dem Jahre 1945, als Ingenieure in einem Schaltrelais eines Computers (Harvard Mark II-System) eine Motte

Mehr

Experte. I-CH-118 Strukturiert implementieren

Experte. I-CH-118 Strukturiert implementieren Autor des Dokuments Valmir Selmani Erstellt / Aktualisiert am 16.06.2011 / 28.06.2011 Teilnehmer des Projekts: Valmir Selmani, Moritz Kündig, Tobias Künzi Seitenanzahl 13 MTV (Moritz Tobias Valmir) 2011

Mehr

Objektorientierte Programmierung mit Python Polymorphismus und Vererbung. Eltern

Objektorientierte Programmierung mit Python Polymorphismus und Vererbung. Eltern Objektorientierte Programmierung mit Python Polymorphismus und Vererbung Eltern Kind Kind Kind Kind Prinzipien der objektorientierten Programmierung Vererbung Strukturierung von Klassen. Oberbegriffe beschreiben

Mehr

Grundlagen der Verwendung von make

Grundlagen der Verwendung von make Kurzskript zum Thema: Grundlagen der Verwendung von make Stefan Junghans Gregor Gilka 16. November 2012 1 Einleitung In diesem Teilskript sollen die Grundlagen der Verwendung des Programmes make und der

Mehr

Projekt: Programmierung mit dem. Grafikfähiger Taschenrechner CASIO CFX-9850GB Plus

Projekt: Programmierung mit dem. Grafikfähiger Taschenrechner CASIO CFX-9850GB Plus Projekt: Programmierung mit dem Grafikfähiger Taschenrechner CASIO CFX-9850GB Plus Inhalt: Programmerstellung am GTR Erstes Programm: Hello world Methoden Text und Zahlen auszugeben Eingabemethoden Vergleichsoperationen

Mehr

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.

Mehr

3 FORMELN. 3.1. Formeln erzeugen

3 FORMELN. 3.1. Formeln erzeugen Formeln Excel effektiv 3 FORMELN 3.1. Formeln erzeugen Übungen: Quittung... 136 Kalkulation... 138 Bestellung... 128 Kassenbuch.. 132 Aufmaß... 152 Zum Berechnen verwendet Excel Formeln. Diese sind in

Mehr

Codierungstheorie Rudolf Scharlau, SoSe 2006 9

Codierungstheorie Rudolf Scharlau, SoSe 2006 9 Codierungstheorie Rudolf Scharlau, SoSe 2006 9 2 Optimale Codes Optimalität bezieht sich auf eine gegebene Quelle, d.h. eine Wahrscheinlichkeitsverteilung auf den Symbolen s 1,..., s q des Quellalphabets

Mehr

Grundlagen der Programmierung 2. Bäume

Grundlagen der Programmierung 2. Bäume Grundlagen der Programmierung 2 Bäume Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 24. Mai 2006 Graphen Graph: Menge von Knoten undzugehörige (gerichtete oder ungerichtete)

Mehr

Mathematische Grundlagen der Kryptographie. 1. Ganze Zahlen 2. Kongruenzen und Restklassenringe. Stefan Brandstädter Jennifer Karstens

Mathematische Grundlagen der Kryptographie. 1. Ganze Zahlen 2. Kongruenzen und Restklassenringe. Stefan Brandstädter Jennifer Karstens Mathematische Grundlagen der Kryptographie 1. Ganze Zahlen 2. Kongruenzen und Restklassenringe Stefan Brandstädter Jennifer Karstens 18. Januar 2005 Inhaltsverzeichnis 1 Ganze Zahlen 1 1.1 Grundlagen............................

Mehr

Diese Anleitung bezieht sich auf FixFoto, V 3.40. In älteren oder neueren Versionen könnte die Arbeitsweise anders sein.

Diese Anleitung bezieht sich auf FixFoto, V 3.40. In älteren oder neueren Versionen könnte die Arbeitsweise anders sein. Pfade einstellen Stand: Dezember 2012 Diese Anleitung bezieht sich auf FixFoto, V 3.40. In älteren oder neueren Versionen könnte die Arbeitsweise anders sein. Diese Anleitung soll zeigen, wie man Pfad-Favoriten

Mehr

1 Oberfläche zum Ausführen der PHP-Dateien

1 Oberfläche zum Ausführen der PHP-Dateien 1 Oberfläche zum Ausführen der PHP-Dateien PHP-Skripte werden vom Webserver ausgeführt. Wenn lokal am Rechner PHP-Dateien erstellt und getestet werden, dann ist es erforderlich, sie im Internet-Explorer

Mehr

Datenbanksysteme SS 2007

Datenbanksysteme SS 2007 Datenbanksysteme SS 2007 Frank Köster (Oliver Vornberger) Institut für Informatik Universität Osnabrück Kapitel 9c: Datenbankapplikationen Architektur einer Web-Applikation mit Servlets, JSPs und JavaBeans

Mehr

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 16

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 16 Kapitel 5 Arithmetische Operatoren Seite 1 von 16 Arithmetische Operatoren - Man unterscheidet unäre und binäre Operatoren. - Je nachdem, ob sie auf einen Operanden wirken, oder eine Verknüpfung zweier

Mehr

5. Programmieren mit Pascal

5. Programmieren mit Pascal 5. Programmieren mit Pascal 5.0. Einführung 5.0.1. Die Datenorganisation Das Betriebssystem auf unserer vernetzten Rechneranlage heißt Windows XP. Ein Betriebssystem versetzt als Basisprogramm den Rechner

Mehr

Grundlagen der Informatik - 6. Praktikum

Grundlagen der Informatik - 6. Praktikum Grundlagen der Informatik - 6. Praktikum In diesem Praktikum soll es neben der Anwendung von Funktionsdefinitionen auch um einfache Prinzipien der verteilten Quelltext-Strukturierung gehen. Diese spielt

Mehr

Python Programmierung. Dipl.-Ing.(FH) Volker Schepper

Python Programmierung. Dipl.-Ing.(FH) Volker Schepper Python Programmierung Kontaktdaten Homepage: http://wwwlehre.dhbw-stuttgart.de/~schepper/ Email: Volker. Schepper [A@T] yahoo.de Vorlesung Skriptsprachen Vorlesung: 06.03.2013 13.03.2013 20.03.2013 27.03.2013

Mehr

Programmieren in C/C++ und MATLAB

Programmieren in C/C++ und MATLAB Programmieren in C/C++ und MATLAB Sven Willert Christian-Albrechts-Universität zu Kiel CAU 2-1 Datentypen und Formate Mit der Festlegung des Datentyps wird die Art bestimmt, mit der der Computer die Informationen

Mehr

Anweisungsblöcke (dazu zählen auch Programme) werden in geschweifte Klammern eingeschlossen.

Anweisungsblöcke (dazu zählen auch Programme) werden in geschweifte Klammern eingeschlossen. Programmierung in C++ Seite: 1 Beispielprogramm 1: Programmierung in C++ int main() int hoehe = 3; int grundseite = 5; double flaeche = hoehe*grundseite*0.5; cout

Mehr

Lenstras Algorithmus für Faktorisierung

Lenstras Algorithmus für Faktorisierung Lenstras Algorithmus für Faktorisierung Bertil Nestorius 9 März 2010 1 Motivation Die schnelle Faktorisierung von Zahlen ist heutzutage ein sehr wichtigen Thema, zb gibt es in der Kryptographie viele weit

Mehr

Kurs 1575, Musterlösung zur Winter Klausur 2002/03

Kurs 1575, Musterlösung zur Winter Klausur 2002/03 1 0 Kurs 1575, Musterlösung zur Klausur im Wintersemester 2002/03 1 Kurs 1575, Musterlösung zur Winter Klausur 2002/03 Aufgabe 1: Warteschlange Wer kennt das Problem nicht? Sie wollen noch schnell im Supermarkt

Mehr

Hansa-Gymnasium Scheme-Einführung Uwe Debacher 2007-1 -

Hansa-Gymnasium Scheme-Einführung Uwe Debacher 2007-1 - - 1 - Alle heute gebräuchlichen Computer-Sprachen fallen unter den Oberbegriff problemorientierte Sprachen, womit eine weitgehende Unabhängigkeit gekennzeichnet wird von der Maschine auf der die Software

Mehr

JSF Erstellen einer einfachen Bankanwendung mit Kontoübersicht und Überweisung

JSF Erstellen einer einfachen Bankanwendung mit Kontoübersicht und Überweisung Universität Bayreuth Lehrstuhl für Angewandte Informatik IV Datenbanken und Informationssysteme Prof. Dr.-Ing. Jablonski JSF Erstellen einer einfachen Bankanwendung mit Kontoübersicht und Überweisung Dipl.

Mehr

Informatik 12 Datenbanken SQL-Einführung

Informatik 12 Datenbanken SQL-Einführung Informatik 12 Datenbanken SQL-Einführung Gierhardt Vorbemerkungen Bisher haben wir Datenbanken nur über einzelne Tabellen kennen gelernt. Stehen mehrere Tabellen in gewissen Beziehungen zur Beschreibung

Mehr

Kapitel 3 Das Projekt Bankkonto Seite 1

Kapitel 3 Das Projekt Bankkonto Seite 1 Kapitel 3 Das Projekt Bankkonto Seite 1 3 Das Projekt Bankkonto Nun wirst du dich etwas gründlicher mit dem Quelltext einer Klasse beschäftigen. Du lernst, wie zwei Objekte eine gemeinsame Aufgabe erledigen.

Mehr

Java-Vorkurs 2015. Wintersemester 15/16

Java-Vorkurs 2015. Wintersemester 15/16 Java-Vorkurs 2015 Wintersemester 15/16 Herzlich Willkommen! package de.unistuttgart.47.01.javavorkurs; public class WelcomeErstis { public static void main(string[] args){ System.out.println( Herzlich

Mehr

Das Handbuch zu KSystemLog. Nicolas Ternisien

Das Handbuch zu KSystemLog. Nicolas Ternisien Nicolas Ternisien 2 Inhaltsverzeichnis 1 KSystemLog verwenden 5 1.1 Einführung.......................................... 5 1.1.1 Was ist KSystemLog?................................ 5 1.1.2 Funktionen.....................................

Mehr

Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book

Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book Gratis Excel SVERWEIS Funktions-Anleitung, Tutorial, ebook, PDF-E-Book Wir wollen wissen wieviel Umsatz Vertreter Müller im Juni gemacht hat? Dazu klicken wir irgendwo in ein Feld und geben ein: =SVERWEIS

Mehr

Übung 4: Schreiben eines Shell-Skripts

Übung 4: Schreiben eines Shell-Skripts Aufgabenteil 1 Ziel der Übung Übung 4: Schreiben eines Shell-Skripts Anhand eines einfachen Linux-Skripts sollen die Grundlagen der Shell-Programmierung vermittelt werden. Das für die Bash-Shell zu erstellende

Mehr

Vom Taschengeld zum Haushaltsbudget

Vom Taschengeld zum Haushaltsbudget Mithilfe eines Tabellenkalkulationsprogramms kannst du Tabellen erstellen, Daten erfassen und auswerten, Kosten ermitteln, Diagramme erstellen, Notendurchschnitte errechnen usw. Die Dateien können als

Mehr

WICHTIG!: Speichern Sie die Backup Datei außerhalb Safe and itunes. Für weitere Infos schauen Sie bitte unter Safe Backup erstellen.

WICHTIG!: Speichern Sie die Backup Datei außerhalb Safe and itunes. Für weitere Infos schauen Sie bitte unter Safe Backup erstellen. Safe Anleitung Safe erlaubt Ihnen Ihre sensiblen Daten zu organisieren und zu speichern. Sie können beliebige Kategorien zur Organisation Ihrer Daten erstellen. Wir bieten Ihnen vordefinierte Vorlagen

Mehr

Programmieren. 10. Tutorium 4./ 5. Übungsblatt Referenzen

Programmieren. 10. Tutorium 4./ 5. Übungsblatt Referenzen Programmieren 10. Tutorium 4./ 5. Übungsblatt Inhalt I. Übungsblatt 4 II. III. - Rückgabe und Besprechung - Vorbereitung auf Wiederholung/ Nachtrag - Operatorpräzedenzen IV. Übungsblatt 5 - Vorstellung

Mehr

17.2 MS-Access Projekte

17.2 MS-Access Projekte 964 Von MS-Access 2000 zum SQL-Server 17.2 MS-Access Projekte MS-Access-Projekte, die die Dateiendung adp besitzen, werden als Front-End-Anwendung verwendet. Für die Back-End-Seite gibt es mehrere Möglichkeiten.

Mehr

Informatik I WS 07/08 Tutorium 24

Informatik I WS 07/08 Tutorium 24 Info I Tutorium 24 Informatik I WS 07/08 Tutorium 24 15.11.07 Bastian Molkenthin E-Mail: infotut@sunshine2k.de Web: http://infotut.sunshine2k.de Review / Organisatorisches o Probleme bei Foliendownload?

Mehr

VWA Rhein-Neckar Dipl.-Ing. Thomas Kloepfer. Kommunikation I (Internet) Übung 4 PHP

VWA Rhein-Neckar Dipl.-Ing. Thomas Kloepfer. Kommunikation I (Internet) Übung 4 PHP VWA Rhein-Neckar Dipl.-Ing. Thomas Kloepfer Kommunikation I (Internet) Übung 4 PHP SS 2004 Inhaltsverzeichnis 1. PHP die serverseitige Programmiersprache...1 1.1. PHP - Bereiche in HTML definieren...1

Mehr

Java programmieren: Konsolen-Programme

Java programmieren: Konsolen-Programme Java programmieren: Es war einmal vor langer Zeit in einer weit entfernten Galaxis ok, das ist etwas übertrieben. In den Anfängen der Personal Computer in den 1980er sahen Computer noch etwa so aus: Diese

Mehr

Das Studiengangsinformationssystem (SGIS)

Das Studiengangsinformationssystem (SGIS) Das Studiengangsinformationssystem (SGIS) Manual für Typo3-Redakteure Version 1.a Mai 2015 Kontakt: Referat 1.4 - Allgemeine Studienberatung und Career Service Christian Birringer, christian.birringer@uni-rostock.de

Mehr

FileMaker und PHP Workshop

FileMaker und PHP Workshop FileMaker und PHP Workshop 2-stündiger Ausschnitt aus einem 3-tägigen Schulungsprogramm Bernhard Schulz FileMaker Konferenz 2010 / Zürich Ziel des Workshops Kennenlernen von PHP Möglichkeiten von FileMaker

Mehr

Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen

Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen Professur für Künstliche Intelligenz und Softwaretechnologie Sommersemester 2009 Überblick Teil 1: Lexen und Parsen Die Sprache LFP +C Professur

Mehr

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 18

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 18 Kapitel 3 Datentypen und Variablen Seite 1 von 18 Datentypen - Einführung - Für jede Variable muss ein Datentyp festgelegt werden. - Hierdurch werden die Wertemenge und die verwendbaren Operatoren festgelegt.

Mehr

Programmierung und Modellierung

Programmierung und Modellierung Programmierung und Modellierung Terme, Suchbäume und Pattern Matching Martin Wirsing in Zusammenarbeit mit Moritz Hammer SS 2009 2 Inhalt Kap. 7 Benutzerdefinierte Datentypen 7. Binärer Suchbaum 8. Anwendung:

Mehr

DHBW Karlsruhe, Vorlesung Programmieren, Klassen (2)

DHBW Karlsruhe, Vorlesung Programmieren, Klassen (2) DHBW Karlsruhe, Vorlesung Programmieren, Klassen (2) Aufgabe 3 Bankkonto Schreiben Sie eine Klasse, die ein Bankkonto realisiert. Attribute für das Bankkonto sind der Name und Vorname des Kontoinhabers,

Mehr

Computerarithmetik ( )

Computerarithmetik ( ) Anhang A Computerarithmetik ( ) A.1 Zahlendarstellung im Rechner und Computerarithmetik Prinzipiell ist die Menge der im Computer darstellbaren Zahlen endlich. Wie groß diese Menge ist, hängt von der Rechnerarchitektur

Mehr

Kapitel 5: PowerShell-Skripte

Kapitel 5: PowerShell-Skripte Kapitel 5: PowerShell-Skripte Abseits der interaktiven Ausführung kann die PS auch Skripte verarbeiten, die mit der Dateierweiterung ".ps1" gekennzeichnet werden. Die "1" steht für die Version der PS.

Mehr

Perzentile mit Hadoop ermitteln

Perzentile mit Hadoop ermitteln Perzentile mit Hadoop ermitteln Ausgangspunkt Ziel dieses Projektes war, einen Hadoop Job zu entwickeln, der mit Hilfe gegebener Parameter Simulationen durchführt und aus den Ergebnissen die Perzentile

Mehr

3.2 Binäre Suche. Usr/local/www/ifi/fk/menschen/schmid/folien/infovk.ppt 1

3.2 Binäre Suche. Usr/local/www/ifi/fk/menschen/schmid/folien/infovk.ppt 1 3.2 Binäre Suche Beispiel 6.5.1: Intervallschachtelung (oder binäre Suche) (Hier ist n die Anzahl der Elemente im Feld!) Ein Feld A: array (1..n) of Integer sei gegeben. Das Feld sei sortiert, d.h.: A(i)

Mehr

E-Commerce: IT-Werkzeuge. Web-Programmierung. Kapitel 4: Einführung in JavaScript Stand: 03.11.2014. Übung WS 2014/2015. Benedikt Schumm M.Sc.

E-Commerce: IT-Werkzeuge. Web-Programmierung. Kapitel 4: Einführung in JavaScript Stand: 03.11.2014. Übung WS 2014/2015. Benedikt Schumm M.Sc. Übung WS 2014/2015 E-Commerce: IT-Werkzeuge Web-Programmierung Kapitel 4: Stand: 03.11.2014 Benedikt Schumm M.Sc. Lehrstuhl für ABWL und Wirtschaftsinformatik Katholische Universität Eichstätt-Ingolstadt

Mehr

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Suche schlecht beschriftete Bilder mit Eigenen Abfragen Suche schlecht beschriftete Bilder mit Eigenen Abfragen Ist die Bilderdatenbank über einen längeren Zeitraum in Benutzung, so steigt die Wahrscheinlichkeit für schlecht beschriftete Bilder 1. Insbesondere

Mehr

EUID. []Ihr persönlicher Code * 1 von 23 25.09.2014 13:52. Liebe Teilnehmerinnen und Teilnehmer an unserem Begleitprojekt,

EUID. []Ihr persönlicher Code * 1 von 23 25.09.2014 13:52. Liebe Teilnehmerinnen und Teilnehmer an unserem Begleitprojekt, 1 von 23 25.09.2014 13:52 Liebe Teilnehmerinnen und Teilnehmer an unserem Begleitprojekt, nochmals vielen Dank für Ihre Bereitschaft an unserem Projekt teilzunehmen. Wir sind mittlerweile beim letzten

Mehr

Fehlermeldung, wenn Anzahl der %do der %end entspricht - was läuft falsch?

Fehlermeldung, wenn Anzahl der %do der %end entspricht - was läuft falsch? News Artikel Foren Projekte Links Über Redscope Join List Random Previous Next Startseite Foren Allgemeine Fragen zu SAS Fehlermeldung, wenn Anzahl der %do der %end entspricht - was läuft falsch? 14 April,

Mehr

Zur Universalität der Informatik. Gott ist ein Informatiker. Die Grundordnung der Welt läßt sich mathematisch formulieren:

Zur Universalität der Informatik. Gott ist ein Informatiker. Die Grundordnung der Welt läßt sich mathematisch formulieren: Daten und ihre Codierung Seite: 1 Zur Universalität der Informatik Gott ist ein Informatiker Die Grundordnung der Welt läßt sich mathematisch formulieren: Naturgesetze, wie wir sie in der Physik, Chemie

Mehr

PHP Einsteiger Tutorial Kapitel 4: Ein Email Kontaktformular in PHP Version 1.0 letzte Änderung: 2005-02-03

PHP Einsteiger Tutorial Kapitel 4: Ein Email Kontaktformular in PHP Version 1.0 letzte Änderung: 2005-02-03 PHP Einsteiger Tutorial Kapitel 4: Ein Email Kontaktformular in PHP Version 1.0 letzte Änderung: 2005-02-03 Bei dem vierten Teil geht es um etwas praktisches: ein Emailformular, dass man auf der eigenen

Mehr