Files
eidp-2024/Tutorium/tut07
Nils Pukropp b907cb789e init
2024-09-16 21:02:27 +02:00
..
2024-09-16 21:02:27 +02:00
2024-09-16 21:02:27 +02:00
2024-09-16 21:02:27 +02:00

Tutorium 07 - 01.12.2023

Execrise 06

img not found

  • 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
    • 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
Studienleistung WS2022
Notenverteilung WS2022

Also, macht eure Aufgaben selber!


Advent of Code

  • Aktuell gibt es wie jedes Jahr wieder Advent of Code.
  • Jeden Tag eine neue Aufgabe
  • Von einfach bis unmenschlich schwer (tendenziell eher einfach)
  • insane Storyline
  • Tag 1 ist schon da!
  • Auch sehr nice um neue Sprachen zu lernen
  • Persönliche Empfehlungen:
    • Rust - Multi-paradigm mit einzigartigen Konzepten
    • Haskell - Funktionale Programmierung
    • Go - OOP, High-Level Programming, sehr einfach Projekte mit aufzusetzen!
    • Zig - Low-Level Programming, rein prozedural, C-Alternative

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"

      \alpha(0, m) = m + 1
      \alpha(n, 0) = \alpha(n - 1, 1)
      \alpha(n, m) = \alpha(n, \alpha(n, m - 1))

      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[tuple[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
      

Fragen?