Aufgaben für das Programmierpraktikum (k-fach-Bachelor-/Masterarbeit)

ist bereits in Bearbeitung durch mehrere Studierende, aber es gibt so viel zu tun, dass weitere willkommen sind.

Im Bachelorstudiengang Informatik wird es ab Sommersemester 2024 ein Programmierpraktikum (5 LP) geben, das das Modul "Softwaretechnik" ergänzt und für die handwerklichen Grundlagen einer professionellen Softwareentwicklung für Einzelpersonen (nicht Teams) sorgen soll: Kenntnis der Programmiersprache, Umgang mit Bibliotheken, mit automatisierten Tests, mit Bestandscode, mit den wichtigsten Werkzeugen, etc.

Zusammen liefern die beiden Module die Voraussetzungen für das Modul "Softwareprojekt", in dem die Arbeit im Team im Mittelpunkt steht.

Wir entwickeln das Gesamtkonzept für das Programmierpraktikum und die zahlreichen Einzelaufgaben gemeinsam als Team, aber durch Abgrenzung gewisser Themenbereiche entstehen dabei separate Abschlussarbeiten.


Prinzipien des Programmierpraktikums

  • Wahlprinzip: Die Studierenden sollen eine möglichst große Freiheit dabei genießen, wie sie agieren wollen. Dies betrifft mehrere Aspekte:
    • Sie können aus einer Menge von zu füllenden Aufgaben überwiegend selbst auswählen.
    • Sie können die inhaltliche Füllung der meisten Aufgaben selbst definieren
    • Sie können insbesondere selbst die Programmiersprache auswählen
  • Zeitumfangsprinzip: Jede Aufgabe bekommt einen erwarteten Zeitaufwand in der Zeiteinheit "halbe Stunde". Aufgaben sind 1 bis 10 halbe Stunden groß. Die Studierenden müssen in der Summe Aufgaben im erwarteten Umfang von 150 Stunden (5 LP) absolvieren, um das Programmierpraktikum zu bestehen. Das Modul ist nicht benotet.
  • Selbständigkeitsprinzip: Die Auswahl und Bearbeitung der Aufgaben kann völlig selbständig, losgelöst von irgendwelchen festen Veranstaltungszeiten erfolgen.
    Die Studierenden müssen feste Zeiten nur einhalten, wenn Sie Päckchen von gelösten Aufgaben zur Kontrolle bei einer Tutor_in vorlegen möchten.
  • Entkopplungsprinzip: Überwiegend können die Studierenden die Aufgaben in jeder gewünschten Reihenfolge abarbeiten. Eine Ausnahme ist der Basisbereich, der als erstes bearbeitet werden muss. Ansonsten gibt es nur bei manchen Aufgaben eine oder wenige andere Aufgaben, die eine (dann explizit benannte) Voraussetzung für die Bearbeitung darstellen.
  • Paararbeitsprinzip: Die Studierenden werden ermuntert, die Aufgaben (aber nicht die Formulierung der eigentlichen Abgabe) in Paarprogrammierung zu erledigen. Wer möchte, darf aber auch allein arbeiten.
  • Verständnisprinzip: Die Leistung, die die Studierenden erbringen, besteht nicht nur darin, ein Arbeitsergebnis vorzuzeigen, sondern sie sollen in der Lage sein, diese Ergebnisse zu erläutern: Was bedeutet das? Wie ist es zustande gekommen? Was war dabei am schwierigsten?
  • Varianzprinzip: Das Programmierpraktikum soll für leistungsschwächere Studierende ohne stark explodierenden Zeitaufwand machbar sein, zugleich aber für sehr leistungsstarke Studierende oder solche mit viel Vorwissen ein interessantes Lernpensum bereithalten. Das wird hauptsächlich durch zwei Maßnahmen erreicht:
    • Es gibt Aufgaben der Schwierigkeitsstufen sehr einfach, einfach, mittel und schwierig. Je nach Leistungsstand sucht man sich bevorzugt ein anderes Niveau heraus.
    • Insbesondere in den Stufen leicht und mittel enthalten die Aufgaben optionale Hilfshinweise, die anfangs nicht sichtbar sind und im Bedarfsfall von den Studierenden aufgeklappt werden.

Aufgaben des Programmierpraktikums

Damit die Teilnehmenden genug Wahlmöglichkeiten haben, sollen insgesamt Aufgaben im Umfang von mindestens 2-3 mal so viel angeboten werden,wie zum Absolvieren des Programmierpraktikums nötig ist, sogar, wenn man die als "schwierig" gekennzeichneten Aufgaben nicht mitrechnet.

Die Ergebnisse sammeln wir hier:

Wie viel gibt es noch zu tun? Viel!
Was gibt es noch zu tun? Dafür schmökert man am besten in die Dateien "how-to.md" und "aufgabenideen.md" in propra-inf.

Die Aufgaben ("tasks") sind eingeteilt in "chapters" (große Themenbereiche) und darin liegende "taskgroups" (Sub-Themenbereiche)

Die Abschlussarbeiten: Allgemeines

Aufteilung der Arbeit, Zusammenarbeit

Wir (d.h. alle Studierenden plus Prof. Prechelt) erarbeiten das Programmierpraktikum als Ganzes im Team. Wir treffen uns wöchentlich (Di 17:00 Uhr) zum Austausch. Jede_r Abschlussarbeiter_in übernimmt mindestens einen Aufgabenbereich weitgehend alleine. Andere Teile werden flexibel aufgeteilt oder sogar gemeinsam bearbeitet; dazu zählt insbesondere vieles, was nicht spezifisch für einzelne Aufgaben ist, sondern Querschnittcharakter hat.

Solche Zusammenarbeit ist kein Problem, solange sie in der schriftlichen Ausarbeitung klar deklariert wird: Wer hat zu dem-und-dem jeweils wie viel beigetragen? Arbeiten von anderen werden insoweit beschrieben, als das zum Verständnis der eigenen Teile sinnvoll ist.

Schriftliche Ausarbeitung: Bachelorarbeit

Die schriftliche Ausarbeitung, deren Umfang laut Prüfungsordnung normalerweise nur ca. 7500 Wörter umfassen soll, also ca. 15 Seiten, beschreibt die Produkte der Arbeit überblickshaft zusammenfassend und konzentriert sich ansonsten auf den Prozess, z.B.:
  • Recherche nach verwandten Arbeiten oder wiederverwendbaren Teilen
  • Überlegungen zur Auswahl der Aufgaben: Didaktische Ziele, Schwerpunkte, bei den Teilnehmenden zu vermeidende Schwierigkeiten, Umfänge usw.
  • Besondere Schwierigkeiten (und ihre Lösung) bei einzelnen Aufgabenstellungen
  • Vor- und Nachteile der gemeinsamen Arbeit; besondere Schwierigkeiten und ihre Lösung
  • Was hat wie lange gedauert und (bei den unerwartet langen Teilen) warum?

Zusätzliche Aspekte für eine Masterarbeit

Die bis hierher beschriebenen Bachelorarbeiten stellen hohe Anforderungen an das informatische Denken, das Wissen und die Urteilskraft. Sie verlangen eine begründete und systematische Herangehensweise und in diesem Sinne ein wissenschaftliches Arbeiten; Sie haben aber nicht den Charakter wissenschaftlicher Forschung. Der ist für eine Masterarbeit jedoch hochgradig wünschenswert.

Deshalb wird die Masterarbeit um einen Forschungsaspekt ergänzt: Evaluation und Qualitätssicherung. Das bedeutet die Bearbeitung z.B. der folgenden Fragen und Aufgaben:
  • Welche Forschung gibt es zu solchen Programmierpraktika?
  • Was sind mögliche didaktische Lernziele?
    => Ziele für unseren Studiengang auswählen und gewichten
  • Welche Aufgabentypen und -formate passen dazu?
    => Erwünschte Profile definieren; Aufgabenentwicklung passend steuern
  • Mit welchen Verfahren bewertet man den Lernerfolg?
    => Auswählen und umsetzen; mit Pilotstudierenden bewerten; Rückschlüsse ziehen und ggf. Maßnahmen einleiten (Aufgabenauswahl)
  • Mit welchen Verfahren bewertet man die Eignung und Qualität der Aufgaben?
    => Auswählen oder entwickeln und ansatzweise umsetzen; Rückmeldung in die Aufgabenentwicklung liefern.
  • das impliziert z.B. an geeigneten Punkten im Verlauf Usability-Prüfungen: Jeweils i.d.R. nur 2-3 Versuchspersonen bearbeiten selbständig eine eng begrenzte Aufgabenstellung und berichten dabei live ("think aloud") oder im Anschluss (Interview) von ihren Erfahrungen, die dann in Verbesserungen umgesetzt werden.
  • Im größeren Stil kann man sich auch Pilotstudierende vorstellen, die das Programmierpraktikum entweder schon "absolvieren" bevor die neue Studienordnung überhaupt in Kraft ist oder die Arbeit als Forschungspraktikum angerechnet bekommen.
  • Wie die Balance ist zwischen solchen analysierenden Maßnehmen einerseits und Verbesserungsarbeiten an den Aufgaben andererseits, müssen wir unterwegs herausfinden.
    Der Fokus bleibt aber ingenieurmäßig: Am Ende wollen wir nicht vor allem Erkenntnisse haben, sondern vor allem ein tolles Programmierpraktikum.

Benotung

Für die Note spielt die schriftliche Ausarbeitung nur eine moderate Rolle; das praktische Arbeitsergebnis in Form von Aufgaben steht im Vordergrund. Die Ausarbeitung ist als eine Art Nebenprodukt der Erarbeitung der Aufgaben anzusehen und verlangt also nicht viel Arbeitszeit. Der bisherigen Erfahrung nach ist der Zeitaufwand für eine Aufgabe ca 4-5 mal so groß, wie der Umfang der Aufgabe. Eine Bachelorarbeit hat 12 LP, also 360 Stunden. Rechnet man für die Ausarbeitung und den Vortrag eineinhalb Wochen ab (60 Stunden), so sollte eine ProPra -Bachelorarbeit ca. Aufgaben im Umfang von 60 Stunden erarbeiten (300 Stunden geteilt durch 5).

Eine sehr gute Arbeit hat diesen Umfang (60 Stunden neue ProPra -Aufgaben) und diese Aufgaben sind praktisch, motivierend, klar und unmissverständlich formuliert, verlangen nur wenig Aufwand in der Schlussredaktion und sind für die Tutor_innen leicht zu kontrollieren.

Eine ausreichende Arbeit hat etwa den halben Umfang (30 Stunden) und die Aufgaben sind weit überwiegend praktischer Natur, aber sie verlangen häufig erhebliche Nacharbeiten, bis sie motivierend genug, klar genug und genügend gut kontrollierbar sind.

Die Abschlussarbeiten

MA Christian Hofmann: Konzipierung eines Programmierpraktikums

Siehe die oben unter "Masterarbeit" beschriebenen Aspekte. Darüber hinaus Hauptverantwortung für den Gesamtablauf, die Qualitätssicherung und den Aufgabenbereich Programmverstehen:
  • sedrila student, sedrila instructor und deren Zusammenspiel mit sedrila author.
    Den Gesamtablauf perfektionieren:
    • Passt alles richtig zusammen?
    • Haben Studis und Tutoren alle (insbes Überblicks-)Funktionen, die sie brauchen?
    • Doku für student, author und instructor bei sedrila; deren Einbettung in propra-inf durch Verweise; oder doch was duplizieren?
    • Ein Rundum-Systemtest für sedrila, der als Smoke-Test alle wichtigen Eigenschaften einmal prüft und das erfolgreiche Zusammenspiel sicherstellt.
  • Durchsicht aller Aufgaben; Rückmeldungen an die Autoren in Richtung eines einheitlichen Aufgabenstils.
  • Schlussredaktion und Freigabe von Aufgaben.
  • Aufgabengruppen zum Thema Programmverstehen: Wie erschließt man sich für ein gegebenes Arbeitsziel ein geeignetes Teilverständnis einer großen Codebasis?
    Lernziel: Überwindung des Gefühls der Hilflosigkeit; Grundkenntnisse in 2-4 verschiedenen Taktiken zum Aufbau von Verständnis (z.B. Codelesen, Tracing/Stepping, statische Codeanalyse/Maße) und diverser Handlungsbausteine für jede davon
  • Mitarbeit an den Aufgaben zur Webentwicklung

MA Daniel Müllers: Didaktik insgesamt, Aufgaben des Programmierpraktikums zu Web-Programmierung

  • HTML und CSS
  • Javascript, DOM
  • HTTP, Cookies und Applicationserver
  • Frontend-Programmierung
  • Zusammenarbeit mit Backends
  • Ferner Hilfe für alle Aufgabenschreibenden zur Didaktik von Aufgaben oder Aufgabengruppen

BA Hanen Alrwasheda: Aufgaben des Programmierpraktikums zu Python-Sprachkonstrukten

  • Aufgabengruppen Python1 (Python-Grundlagen, die eigentlich bekannt sein sollten) und Python2 (fortgeschrittene Sprachkonstrukte und ihre Verwendung, immer mit praktischer Anwendung).

BA Sven Wegner: Aufgaben des Programmierpraktikums zur Python-Standardbibliothek

  • Kleine, praktische Einführungen in jeweils eines oder wenige der wichtigsten Module der Standardbibliothek.
  • Ggf. zusätzliche fortgeschrittene Aufgaben zu wichtigen Modulen.

BA Dominik Pietrak: Aufgaben des Programmierpraktikums zu Debugging und Refactoring

  • siehe Repo propra-inf
  • Debugging: Erlernen einer handvoll methodischer Elemente für erfolgreiches Debugging (Prinzipien, abstrakte Schrittfolge aus: Reproduzieren, Erkundend weiterbeobachten, Hypothesebilden, Hypotheseprüfen) und handwerklicher Aspekte dazu (Codelesen, ad-hoc print-Debugging, dauerhafteres log-Debugging, automatisierte Tests, Benutzung des Debuggers, Refactoring)
  • Refactoring (jeweils: Mechanik verstehen, üben, sinnvolle Einsatzfälle verstehen, üben): Rename, Extract Variable, Extract Method. Evtl. fortgeschrittenere. Grenzen der IDE verstehen, z.B. aufgrund von Polymorphie, aufgrund von dynamischer Typisierung.

BA Sven Hüster: Aufgaben des Programmierpraktikums zu Git und Shell

  • Git1: Beherrschung des Basissatzes von Kommandos mit gutem konzeptuellen Verständnis dafür, was sie bedeuten (d.h. bewirken). Commit, Tree, Blob. Refspec.
  • Git2: Kenntnis (mit mindestens Ausprobieren oder besser noch richtigem Üben) der Idiome für alltägliche Situationen wie: Rebase/Merge mit Konflikten; Rückgängigmachen von Schritten; Unterbrechen von Arbeiten (stash); etc.
    Hier kann man schön Gebrauch von der Paararbeit machen, indem die beiden parallel am gleichen Repo arbeiten!
  • Git 3: Fortgeschrittene Kommandos (jedenfalls ein paar wichtigere davon)
  • Shell interaktiv (bash): Globbing, Pipes, Umlenkung, Variablen, Prompt bauen, Aliases, history, history substitution, man
  • Shellprogrammierung: sh, bash (Pipes, Umlenkung, Variablen, if/else, for, while, Spezialvariablen, Unterprogramme, Quoting, statuscodes (siehe z.B. curl), …).
    Lernziel: Situationen verstehen, in denen man das jeweils gebrauchen kann.
    Mindestens ein nicht-triviales Shellskript selbst schreiben und eines verstehen und modifizieren.
  • Umgang mit Dateien: ls, mv, rm, cp, mkdir, rmdir, ….
    Lernziel: die Fälle verstehen, in denen das einer GUI überlegen ist: mit Globbing, mit mehreren Argumenten, mit speziellen Optionen
  • Typische Helfer für die Shellprogrammierung (wie touch, cat, head, tail, grep, uniq, sort, find, awk, sed, xargs, tee, …) und typische Idiome.
    Lernziel: Je mindestens einen gut erinnerbaren Anwendungsfall ausprobieren, in dem das Helferlein gute Dienste leistet.

BA Ronny Ruhe: Aufgaben des Programmierpraktikums zum Aufgabenfeld Testen

  • Testgrundlagen: Fehler, Testpyramide, Testfälle, Testabgränzungen zum Debugging
  • API: CRUD, RestAPI, Responses
  • Unittests: mit unittest, pytest, mocking, Testabdeckung, tdd, Pairprogramming, Anwendungen mit unittest & pytest
  • Testframeworks: Robot Framework, Locust, Gherkin, Playwright
  • Bestandscode: ein webbasiertes SUT für die praktsichen Aufgaben im Testbereich
  • Linting: black, bandit, flake8, isort, markdownlint
Abseits davon - Aufgaben die als referenz für das aktiove Testen verwendet werden können:
  • SQL Taskgroup, Basics, Joins, Selects und Projektaufgabe
  • Python praxis Anteile: Passwortgenerator

BA Ivan Condric: Aufgaben des Programmierpraktikums zu Netzwerk und Systemadministration

  • ssh: Schlüsselpaar erzeugen, ~/.ssh, ssh, ssh-agent, tmux, …
  • lokales System, z.B. evtl.: w, uptime, whoami, df, du, tail -f, mount, ps, pgrep, kill/pkill, top/htop, ...
    Lernziel: Situationen verstehen, in denen man das jeweils gebrauchen kann.
  • Mitarbeit bei "Typische Helfer für die Shellprogrammierung" (Hüster)
  • Dateisystemaufbau: /bin, /usr, /var, /etc, /mnt, ...
    Lernziel: Grobes Verständnis von "Was ist wo?"
  • fortgeschrittenes Dateihandling: file, dd, tar, zip, gzip, …
  • root sein, z.B. evtl.: sudo (mit sudoers, visudo etc.), su, Ethos, Vorsicht, /etc/passwd, Gruppen/Gruppenrechte, …
  • Netz, z.B. evtl.: ping, rsync, curl, wget, …

Weitere mögliche Themenkreise

Es kommen beispielsweise in Frage:

  • Wichtige sehr große (Python)Bibliotheken, z.B. numpy/pandas, matplotlib oder andere.
    Ferner die Methoden, wie man eine Bibliothek auswählt, wenn es mehrere gibt. Siehe zu beidem die Notizen in aufgabenideen.md.
  • Weitere wichtige Programmiersprachen (und ggf. deren Standardbibliotheken), insbesondere C, Scala, SQL, Go, Java.
  • Noch so einiges aus dem Bereich Webprogrammierung.
  • Informationssicherheit (Security): Typische Muster von Mängeln (CWE, OWASP Top 10), Werkzeuge zur Suche von Mängeln, Muster und Werkzeuge für's Richtigmachen.

Bei Interesse an einem solchen Sektor bitte etwas einlesen, erste Aufgabenideen entwickeln und dann gern zu Lutz Prechelt in die Sprechstunde kommen.




Rückfragen gern an Lutz Prechelt.

Letzte Version dieser Seite mit den dann gelöschten vielen Einzelheiten war Revision 10.