Tutorium 07 - 01.12.2023
Execrise 06
- Korrektur wieder am Samstag
Problematik ChatGPT und Plagiate
- ChatGPT ist ein tolles Tool, warum?
- Manchmal liefert es andere Lösungen zu Problemen
- Grundverständnis bei neuen Problemen
- integriert in die IDE (z.B. Github Copilot):
- schneller Code schreiben
Wie viele Zeilen Code schreibt ein Entwickler durchschnittlich am Tag?
10 bis 50 Codezeilen - Leichtsinnsfehler ausbessern
- schneller Code schreiben
- Kurz: Es nimmt einen repetetive Arbeit ab
Die Problematik?
- Ein EidP soll das Grundverständnis von Programmieren vermittelt werden
- Denkweise
- Konzepte in der theoretischen Informatik
- Konzepte in Programmiersprachen
- Übung
- Um ChatGPT sinnvoll zu nutzen müsst ihr diese Grundverständnis bereits besitzen
- Auch Studierende mit Vorwissen profitieren davon die Übung sinnvoll zu bearbeiten
- Wenn Ihr für die Aufgaben ChatGPT verwendet, dann habt ihr nicht genug Vorwissen
Also, macht eure Aufgaben selber!
Wichtiges/Hilfreiches für Exercise-07
Rekursion
- Rekursion in Python sind Funktionen die sich selbst aufrufen
def fac(n: int) -> int: if n <= 1: # Abbruchbedingung, kein Rekursiver Aufruf mehr! return 1 return n * fac(n - 1) # Rekursiver Aufruf
- Eine Rekursion braucht eine Abbruchbedingung
- primitive Rekursionen können auch einfach iterative gelöst werden
def fac2(n: int) -> int: fac = 1 for i in range(1, n + 1): fac *= i return fac
- Eine Rekursion kann mehrere Rekursionspfade haben! (Kaskadenförmige Rekursion), welche auch primitiv berechenbar sind!
def fib(n: int) -> int: if n in {0, 1}: # Abbruchbedingung return n return fib(n - 1) + fib(n - 2) # mehrere Rekursionsaufrufe
- Wie Funktioniert das?
-
Es wird ein Rekursionsbaum aufgebaut
-
Wenn dieser Fertig ist wird berechnet
-
Z.b.
fac
:fac(5) 5 * fac(4) 5 * 4 * fac(3) 5 * 4 * 3 * fac(2) 5 * 4 * 3 * 2 * fac(1) 5 * 4 * 3 * 2 * 1 120
fib(4) fib(3) + fib(2) (fib(2) + fib(1)) + (fib(0) + fib(1)) ((fib(0) + fib(1)) + fib(1)) + (fib(0) + fib(1)) ((0 + 1) + 1) + (0 + 1) 3
-
- Gibt es Rekursionen die nicht iterative berechenbar sind?
-
$\mu$-Rekursionen oder partiell Rekursionen
-
erste partiell rekursive Funktion von Wilhelm Ackermann 1926, die "Ackermannfunktion" $$\begin{align} \alpha(0, m) &= m + 1 \ \alpha(n, 0) &= \alpha(n - 1, 1) \ \alpha(n, m) &= \alpha(n, \alpha(n, m - 1)) \end{align}$$
def ack(n: int, m: int) -> int: match (n, m): case (0, _): return m + 1 case (_, 0): return ack(n - 1, 1) case _: return ack(n - 1, ack(n, m - 1))
-
Tipp:
Man kann alles rekursiv Aufbauen mit Operatoren (+, -, *, /, %, //, &&, and, ...
), also auch Listen oder Strings
def all_fac(max: int) -> list[(int, int)]:
if max == 0: # Abbruchbedingung
return [(0, 1)]
return [(max, fac(max))] + all_fac(max - 1) # Rekursion
def all_fac_str(min: int, max: int) -> str:
if min >= max: # Abbruchbedingung
return f"{fac(min)}"
return f"{fac(min)} " + all_fac_str(min + 1, max) # Rekursion
def fib_str(n: int) -> str:
if n in {0, 1}: # Abbruchbedingung
return str(n)
return f"({fib_str(n - 1)} + {fib_str(n - 2)})" # Rekursion
Rekursion in Bäumen
- Drei möglichkeiten einen Baum abzulaufen
- Pre-Order: Knoten, links, rechts
def preorder[T](tree: BTree[T]): match tree: case Node(value, left, right): print(value) preorder(left) preorder(right) case _: return
- Post-Order: links, rechts, Knoten
def postorder[T](tree: BTree[T]): match tree: case Node(value, left, right): postorder(left) postorder(right) print(value) case _: return
- In-Order: links, Knoten, rechts
def inorder[T](tree: BTree[T]): match tree: case Node(value, left, right): inorder(left) print(value) inorder(right) case _: return
- Pre-Order: Knoten, links, rechts