--- marp: true paginate: true theme: rose-pine footer: EidP 2024 - Nils Pukropp - https://git.narl.io/nvrl/eidp-2024 style: ".columns {\r display: grid;\r grid-template-columns: repeat(2, minmax(0, 1fr));\r gap: 1rem;\r }" --- # Tutorium 04 - 2024-11-14 Blatt 04, assert, top-level statements, Blatt 05 --- # Vorab - LFG Rechnernetze - Handynummer: [+49-160-8080619](tel:+491608080619) - Mail: [nils@narl.io](mailto:nils@narl.io) --- # Vorab - Ausfall Tutorium 12.12. - Tutorium am 12.12. fällt aus - Bitte Ersatztutorium auf der [Vorlesungswebsite](https://proglang.github.io/teaching/24ws/eidp.html) aussuchen - Ihr könnt da auch Vorrechnen/Anwesenheitspunkte bekommen --- # Blatt 04 --- # `assert` - Was ist das? - Eine Annahme über einen Zustand - Wird gerne zum Testen verwendet - Wenn die Annahme nicht stimmt, dann *stürzt* euer Programm ab - Wird manchmal als Invariante benutzt --- # `assert` als Invariante - Ihr müsst euch sicher sein, dass die Invariante immer stimmt - z.B. wenn ihr auf dem Blatt mit nur korrekten Eingaben rechnen könnt ```python def input_number() -> int: num = input("Please enter a whole number:\n>") assert num.isnumeric() return int(num) ``` --- # `assert` als Schleifeninvariante - Typischeres Beispiel für Invariante in Informatik ist die Schleifeninvariante - Damit können Beweise über die Korrektheit des Algorithmus gemacht werden --- ```python def multiply(a: int, b: int) -> int: x, y, p = a, b, 0 # Die Schleifeninvariante gilt vor der Schleife assert (x * y) + p == a * b while x > 0: # Die Schleifeninvariante gilt an jedem Schleifenanfang assert (x * y) + p == a * b p = p + y # Zwischendrin muss diese nicht gelten x = x - 1 # Die Schleifeninvariante muss am Ende jedes Durchlaufs gelten assert (x * y) + p == a * b # Die Schleifeninvariante muss ganz am Ende gelten assert (x * y) + p == a * b return p ``` --- # `assert` als Top-Level Statement - es ist aber sehr untypisch seinen ganzen Code mit Invarianten voll zu machen - wir programmieren ja nur korrekte Algorithmen ;) - stattdessen wird assert gerne zum Testen verwendet - Hier muss dann `assert` in die `if __name__ == "__main__":` - Mit genug guten Tests können wir auch davon ausgehen, dass der Algorithmus korrekt ist --- ```python if __name__ == "__main__": assert multiply(3, 4) == 12 assert multiply(0, 1) == 0 assert multiply(1000, 0) == 0 assert multiply(100, 1000) == 100000 ``` --- # Top-Level Statements Wann benutzen wir `if __name__ == "__main__":`? --- # Wann `if __name__ == "__main__":`? - eigentlich immer wenn eine der Folgenden Funktionen benutzt: - `assert` - `print(...)` - `input(...)` - außer es ist anders gefordert! Das steht dann aber explizit dabei --- # Wann `input()/print()`? - Es gibt zwei Aufgaben Typen 1. Implementieren Sie Funktion *f* die `f(...) -> ...` tut. - meistens gibt es `assert` als Beispiele 2. Implementieren Sie ein Programm das von Benutzer `x` fordert und `y` ausgibt. - es gibt immer eine Beispieleingabe/-ausgabe --- # Beispiel Type I Schreiben Sie eine Funktion `multiply` die zwei Zahlen multipliziert ```python def multiply(a: int, b: int) -> int: x, y, p = a, b, 0 while x > 0: p = p + y x = x - 1 return p ``` --- Hier kann man z.B. auch die Tests einfach in die main schreiben: ```python if __name__ == "__main__": assert multiply(3, 4) == 12 assert multiply(0, 1) == 0 assert multiply(1000, 0) == 0 assert multiply(100, 1000) == 100000 ``` --- # Beispiel Type II Schreiben Sie ein [Programm](./src/program.py) was zwei Zahlen nimmt und das Ergebnis ausgibt, das soll solange geschehen bis der Nutzer `exit` schreibt --- # Blatt 05 ---