Algorithmische Grundlagen Sommersemester 2016 – VL01 Martin Mundhenk Uni Jena, Institut für Informatik 4. April 2016 Vorlesung Algorithmische Grundlagen (Sommer 2016) Die Vorlesung/Übung orientiert sich am Buch Introduction to Programming in Python – An Interdisciplinary Approach von Robert Sedgewick, Kevin Wayne und Robert Dondero (Addison Wesley, 2015) Die Webseite zum Buch http://introcs.cs.princeton.edu/python/home/ ist auch für diese Vorlesung nützlich. Organisatorisches § Vorlesung montags, 16-18 Uhr, Raum 3325 Ernst-Abbe-Platz 2 Am Montag, 11.4., beginnt die Vorlesung um 16:30 Uhr § Übung donnerstags, 8-10 Uhr, Raum 3410 (Linux-Pool 2) EAP2 Zur Teilnahme brauchen Sie eine Nutzerkennung beim FRZ! § Es gibt ein wöchentliches Übungsblatt (ca. 12) Abgabe montags 16:15 Uhr (an [email protected]) § Zur Zulassung zur Modulprüfung müssen jeweils mindestens 50% der Punkte der Übungsblätter aus der ersten und der zweiten Hälfte erreicht sein. § Die Abschlussprüfung ist mündlich. Wer will, kann bei der Abschlussprüfung ein Programmierprojekt vorstellen. 1 Elemente des Programmierens Ein Programm zu schreiben ist nicht schwieriger, als einen Aufsatz zu schreiben. Wir schauen uns die Grundbausteine von Python-Programmen an und starten mit dem Programmieren. 1. Elemente des Programmierens 1.1 Grundlegende Daten-Typen 1.2 Verzweigungen und Schleifen 1.3 Arrays 1.4 Ein- und Ausgabe 1.1 Grundlegende Datentypen Typ Werte Operatoren int ganze Zahlen ` ´ ˚ {{ % ˚˚ 2016 -12 11267456 float Dezimalbrüche ` ´ ˚ { ˚˚ 3.14 2.5 6.022e+23 bool Wahrheitswerte and str Zeichenfolgen or ` Beispiele für Literale not True 'AB' False 'Hello world' '2.5' int . . . integer float . . . floating-point number (Fließkommazahl) bool . . . boolean (George Boole, 1815-1864) str . . . string 1.1.1 Grundlegende Begriffe Ein (sehr) einfaches Python-Programm a = 123 b = 99 c = a + b * 2 Das Programm besteht aus drei Anweisungen. Es werden drei Objekte vom Typ int erzeugt. Die Variablen a, b und c werden an sie gebunden. Am Ende ist c an ein Objekt vom Typ int mit Wert 321 gebunden. 123 ist ein Literal, das einen Wert vom Typ int bezeichnet. a + b * 2 ist ein Ausdruck (expression). Der Ausdruck besteht aus Variablen, die an Objekte vom Typ int gebunden sind, einem int-Literal und den Operatoren + und *. Bei der Auswertung des Ausdrucks wird ein (neues) Objekt erzeugt, dessen Wert der Ausdruck beschreibt. 1.1.2 Ausdrücke vom Typ int bestehen aus § Literalen vom Typ int § Variablen, die an Objekte vom Typ int gebunden sind § den Operatoren + - * // % ** § ... + - * stehen für Addition, Subtraktion und Multiplikation. // ist die ganzzahlige Division. 17 // 6 ist 2 (da 17 “ 2 ¨ 6 ` 5), und -17 // 6 ist -3 (da ´17 “ ´3 ¨ 6 ` 1). Mathematische Schreibweise für die ganzzahlige Division: a // b entspricht t ba u txu ist die größte ganze Zahl ď x ( untere Gaußklammer“) ” 1.1.3 % ist der Rest bei der ganzzahligen Division (modulo-Operation). 17 % 6 ist 5 (da 17 “ 2 ¨ 6 ` 5), und -17 % 6 ist 1 (da ´17 “ ´3 ¨ 6 ` 1). Mathematische Schreibweise für a % b ist a mod b . ** ist die Potenz. 3**4 ist 81 (da 34 “ 3 ¨ 3 ¨ 3 ¨ 3 “ 81). Die Operatoren haben unterschiedliche Bindungsstärke (entsprechend Punktrechnung geht vor Strichrechnung“). ” Im Zweifel: Klammern setzen . . . Weitere Beispiele für int-Ausdrücke (mit int-Variablen): Stunden * 60 * 60 + Minuten * 60 + Sekunden (53 - 6) * 40 // LP pro Jahr Jahr - ( ((Monat-3)%12) // 10 ) (49*48*47*46*45*44*43)//(1*2*3*4*5*6) max( a, b ) 1.1.4 Anweisungen assignment statements Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck. Jahrhundertzahl = (Jahr-(((Monat-3)%12)//10))//100 Arbeitsstunden pro LP = (53 - 6) * 40 // LP pro Jahr zaehler = zaehler + 1 Beim Abarbeiten einer Anweisung an eine Variable eines grundlegenden Daten-Typs wird § zuerst der Ausdruck ausgewertet und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, § danach wird die Variable an das Objekt gebunden. 1.1.5 # Berechne das Volumen und die Oberfläche eines Quaders. # Zuerst werden die Maße des Quaders angegeben. Hoehe = 5 Breite = 12 Tiefe = 32 # Daraus können nach den bekannten Formeln # das Volumen und die Oberfläche berechnet werden. Volumen = Hoehe * Breite * Tiefe Oberflaeche = 2 * ( Hoehe*Breite + Hoehe*Tiefe + Breite*Tiefe ) Der Typ str . . . dient dem Verarbeiten von Texten. Literale sind Folgen von Zeichen, die durch ' ... ' eingeschlossen sind. 'Das folgende ist kein int-Literal.' '1234' Die Operation + schreibt Strings hintereinander (Konkatenation). 'Das ist ' + 'ein Satz.' ergibt 'Das ist ein Satz.' . Die Funktion str( ) macht aus einem Objekt einen String. Z.B. liefert str(123) den String '123'. Entsprechend macht die Funktion int( ) aus einem Objekt ein int-Objekt. Z.B. liefert int('123') ein int-Objekt mit Wert 123. 1.1.7 #----------------------------------------------------------------------# ruler.py #----------------------------------------------------------------------import stdio # # # # # Write to standard output the relative lengths of the subdivisions on a ruler. The nth line of output is the relative lengths of the marks on a ruler subdivided in intervals of 1/2^n of an inch. For example, the fourth line of output gives the relative lengths of the marks that indicate intervals of one-sixteenth of an inch on a ruler. ruler1 = '1' ruler2 = ruler1 + ' 2 ' + ruler1 ruler3 = ruler2 + ' 3 ' + ruler2 ruler4 = ruler3 + ' 4 ' + ruler3 stdio.writeln(ruler1) stdio.writeln(ruler2) stdio.writeln(ruler3) stdio.writeln(ruler4) #----------------------------------------------------------------------# python ruler.py # 1 # 1 2 1 # 1 2 1 3 1 2 1 # 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 1.1.8 #----------------------------------------------------------------------# einundausgabe.py #----------------------------------------------------------------------import stdio import sys # Lies drei Strings aus der Kommandozeile # und gib sie in umgekehrter Reihenfolge wieder aus. a = sys.argv[1] b = sys.argv[2] c = sys.argv[3] stdio.writeln( c + ' ' + b + ' ' + a ) #----------------------------------------------------------------------# python einundausgabe.py Hallo Martin . # . Martin Hallo # # python einundausgabe.py Hallo Martin. # Traceback (most recent call last): # File "einundausgabe.py", line 12, in <module> # c = sys.argv[3] # IndexError: list index out of range 1.1.9 int-Werte zu str-Werten umwandeln #------------------------------------------------------------------------# teilen_v1.py #------------------------------------------------------------------------import stdio a = 15 b = 213 stdio.write( str(b) + ' geteilt durch ' + str(a) + ' ergibt ' ) stdio.writeln( str( b//a ) + ' Rest ' + str( b%a ) + '.' ) #------------------------------------------------------------------------# # python teilen_v1.py # 213 geteilt durch 15 ergibt 14 Rest 3. # 1.1.10 str-Werte zu int-Werten umwandeln #------------------------------------------------------------------------# teilen_v2.py #------------------------------------------------------------------------import stdio import sys # Lies zwei Argumente a und b von der Kommandozeile. # Gib den (ganzzahligen) Quotienten und den Rest bei der Division von a durch b aus. a = int( sys.argv[1] ) b = int( sys.argv[2] ) stdio.write( str(a) + ' geteilt durch ' + str(b) + ' ergibt ' ) stdio.writeln( str( a//b ) + ' Rest ' + str( a%b ) + '.' ) #------------------------------------------------------------------------# python teilen_v2.py 1234 23 # 1234 geteilt durch 23 ergibt 53 Rest 15. # # python teilen_v2.py 1234 0 # File "teilen_v2.py", line 13, in <module> # stdio.writeln( str( a//b ) + ' Rest ' + str( a%b ) + '.' ) # ZeroDivisionError: integer division or modulo by zero 1.1.11 Der Typ float . . . dient dem Rechnen mit Dezimalbrüchen. Literale sind z.B. 4.0 123.45 3.141e+12 (steht für 3, 141 ¨ 1012 ) Die Operationen mit float sind + - * / ** . Kommt in einem Ausdruck ein float-Wert vor, dann hat das Ergebnis Typ float (und nicht Typ int). float-Werte haben nur beschränkte Genauigkeit. stdio.writeln(str(1.23456789012345e+12)) hat Ausgabe 1.23456789012e+14 1.1.12 Die quadratische Gleichung a ¨ x 2 ` b ¨ x ` c “ 0 hat die Lösungen ? ´b ˘ b 2 ´ 4 ¨ a ¨ c x1,2 “ . 2¨a # Das Programm mitternacht.py liest float-Werte a, b und c von der Kommandozeile ein # und gibt die beiden durch die Mitternachtsformel bestimmten Lösungen aus. import stdio import sys import math a = float( sys.argv[1] ) b = float( sys.argv[2] ) c = float( sys.argv[3] ) diskriminante = math.sqrt(b**2 - 4 * a * c) stdio.writeln( (-b + diskriminante) / (2*a) ) stdio.writeln( (-b - diskriminante) / (2*a) ) 1.1.13 # Das Programm mitternacht.py liest float-Werte a, b und c von der Kommandozeile ein # und gibt die beiden durch die Mitternachtsformel bestimmten Lösungen aus. import stdio import sys import math a = float( sys.argv[1] ) b = float( sys.argv[2] ) c = float( sys.argv[3] ) diskriminante = math.sqrt(b**2 - 4 * a * c) stdio.writeln( (-b + diskriminante) / (2*a) ) stdio.writeln( (-b - diskriminante) / (2*a) ) #-----------------------------------------------------------------------------------# python mitternacht.py 4 6 2 # -0.5 # -1.0 # python mitternacht.py 1 2 3 # Traceback (most recent call last): # File "mitternacht.py", line 17, in <module> # diskriminante = math.sqrt(b**2 - 4 * a * c) # ValueError: math domain error 1.1.14 float-Werte können ungenau sein #----------------------------------------------------------------------# fehler_mit_float.py #----------------------------------------------------------------------import stdio # 10^16 +1 wird als int-Literal dargestellt, # und 10^16 +1 wird als float-Wert dargestellt. int_zahl = 10000000000000001 float_zahl = 10.0**16 +1 # Beide Zahlen werden ausgegeben. stdio.writeln('int Zahl: ' + str(int_zahl)) stdio.writeln('float Zahl: ' + str(float_zahl)) stdio.writeln('float Zahl als int: ' + str(int(float_zahl))) #----------------------------------------------------------------------# python fehler_mit_float.py # int Zahl: 10000000000000001 # float Zahl: 1e+16 # float Zahl als int: 10000000000000000 1.1.15 Bemerkungen zu Funktionen Eingebaute“ Funktionen: ” str( ), int( ), float( ), bool( ), abs( ) (der Betrag einer Zahl), round( ) (nächster int-Wert), max( , ), min( , ) (Maximum bzw. Minimum zweier Zahlen) . . . Standard-Funktionen aus Standard-Modulen von Python: math.sqrt( ), math.log( , ), random.random() (eine zufällige float-Zahl x mit 0 ď x ă 1), random.randrange(x,y) (eine zufällige int-Zahl aus rx, y q), . . . Funktionen aus den Modulen für das Buch: stdio.write( ), stdio.writeln( ), . . . 1.1.16 Der Typ bool . . . dient dem Rechnen mit Wahrheitswerten True und False. Es gibt die Operation and, or und not auf bool-Objekten. a b False False False True True False True True a and b False False False True a or b False True True True a False True not a True False 1.1.17 Vergleichsoperationen liefern bool-Werte Operator == != < <= > >= Bedeutung Beispiel True False gleich 3==3 2==3 ungleich 2!=3 3!=3 kleiner als 2<3 3<3 kleiner oder gleich 3<=3 4<=3 größer als 4>3 3>4 größer oder gleich 4>=3 3>=4 1.1.18 #----------------------------------------------------------------------# leapyear.py #----------------------------------------------------------------------import stdio import sys # Accept an int year as a command-line argument. Write True to # standard output if year is a leap year. Otherwise write False. year = int(sys.argv[1]) isLeapYear = (year % 4 == 0) isLeapYear = isLeapYear and (year % 100 != 0) isLeapYear = isLeapYear or (year % 400 == 0) stdio.writeln(isLeapYear) #----------------------------------------------------------------------# python leapyear.py 2016 # True # python leapyear.py 1900 # False # python leapyear.py 2000 # True 1.1.19 #----------------------------------------------------------------------# tippspiel.py #----------------------------------------------------------------------import stdio import sys import random # # # # Spieler 1 gibt sein Zahl über die Kommandozeile ein. Anschließend würfelt Spieler 2 (das Programm) eine Zahl aus dem Bereich 1,2,3,4,5,6. Falls beide Spieler eine ungerade Zahl haben oder beide Spieler eine gerade Zahl haben, dann gewinnt Spieler 1. Sonst gewinnt Spieler 2. zahl_von_spieler_1 = int(sys.argv[1]) zahl_von_spieler_2 = random.randrange(1,7) stdio.write('Spieler 1 hat ' + str(zahl_von_spieler_1) + ' gewaehlt und ') stdio.writeln('Spieler 2 hat ' + str(zahl_von_spieler_2) + ' gewuerfelt.') ergebnis = ( (zahl_von_spieler_1 % 2 ) == (zahl_von_spieler_2 % 2) ) stdio.writeln('Spieler 1 gewinnt ist ' + str(ergebnis) + '.') #-------------------------------------------------------------------------# python tippspiel.py 3 # Spieler 1 hat 3 gewaehlt und Spieler 2 hat 3 gewuerfelt. # Spieler 1 gewinnt ist True. 1.1.20 Zusammenfassung § Wir haben die elementaren Daten-Typen int, float, str und bool von Python kennengelernt. § Wir können Ausdrücke aus Literalen, Variablen, Operatoren und Funktionen schreiben. § Wir können sehr einfache Programme mit Eingabe von Argumenten Abarbeitung einer festen Folge von Anweisungen Ausgabe eines Ergebnisses schreiben und deren Ausführung nachvollziehen. 1.1.21