diff --git a/Tutorium/tut05/README.md b/Tutorium/tut05/README.md new file mode 100644 index 0000000..df6b930 --- /dev/null +++ b/Tutorium/tut05/README.md @@ -0,0 +1,166 @@ +--- +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 + +--- diff --git a/Tutorium/tut05/slides.pdf b/Tutorium/tut05/slides.pdf new file mode 100644 index 0000000..94ebe0e Binary files /dev/null and b/Tutorium/tut05/slides.pdf differ diff --git a/Tutorium/tut05/src/asserts.py b/Tutorium/tut05/src/asserts.py new file mode 100644 index 0000000..130c6f7 --- /dev/null +++ b/Tutorium/tut05/src/asserts.py @@ -0,0 +1,22 @@ +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 + + +if __name__ == "__main__": + assert multiply(3, 4) == 12 + assert multiply(0, 1) == 0 + assert multiply(1000, 0) == 0 + assert multiply(100, 1000) == 100000 diff --git a/Tutorium/tut05/src/program-2.py b/Tutorium/tut05/src/program-2.py new file mode 100644 index 0000000..c2d41de --- /dev/null +++ b/Tutorium/tut05/src/program-2.py @@ -0,0 +1,4 @@ +import program + + +print(program.multiply(3, 4)) diff --git a/Tutorium/tut05/src/program.py b/Tutorium/tut05/src/program.py new file mode 100644 index 0000000..431af28 --- /dev/null +++ b/Tutorium/tut05/src/program.py @@ -0,0 +1,19 @@ +def multiply(a: int, b: int) -> int: + x, y, p = a, b, 0 + while x > 0: + p = p + y + x = x - 1 + return p + + +def run() -> None: + while True: + a = input("Bitte geben Sie eine Zahl oder exit ein:\n> ") + if a == "exit": + break + b = input("Bitte geben Sie eine weitere Zahl ein:\n> ") + print(f"{a} * {b} = {multiply(int(a), int(b))}") + + +if __name__ == '__main__': + run()