| Kriterium | Gewicht | ausgezeichnet (30) | gut (25) | akzeptabel (20) | verbesserungswürdig (15) | inakzeptabel (0) |
|---|---|---|---|---|---|---|
| Korrektheit & Funktionalität (check_item, stock_value, reorder_qty, evaluate_inventory) | 30 % | Alle Kernfunktionen korrekt (inkl. Randfälle); evaluate_inventory liefert korrekte Statuslogik (invalid/ok/reorder) und bestimmt priority_product_id sowie total_reorder_qty korrekt. | Weitgehend korrekt; kleine Ungenauigkeiten/Randfälle; Statuslogik und Hauptkennzahlen meist korrekt. | Grundfunktionalität vorhanden, aber mehrere Fehler (z. B. falsche Status oder unvollständige Kennzahlen) oder Teile fehlen. | Läuft nur teilweise; zentrale Berechnungen oder Statuswerte sind fehlerhaft. | Nicht funktionsfähig oder fehlt. |
| Schnittstellen, Kommentare & Kontrollstrukturen | 20 % | Sprechende Parameter & klare Rückgaben; saubere if/else- und Schleifen- oder apply-Struktur; sehr gut kommentiert; konsistenter, lesbarer Stil. | Korrekte Struktur und Kommentare mit kleineren Redundanzen oder Uneinheitlichkeiten. | Nachvollziehbar, aber uneinheitliche Schnittstellen/Benennungen oder knappe Kommentare. | Unstrukturierter Code, wenig oder keine Kommentare; schwer lesbar. | Logik nicht nachvollziehbar; Struktur fehlt. |
| Validierungen & Fehlerbehandlung (check_item) | 20 % | Umfassende Plausibilitätsprüfungen (Typen, Länge, fehlende Werte, Wertebereiche) mit klaren Begründungen; keine stillen Fehler. | Die meisten relevanten Prüfungen vorhanden; einzelne Lücken oder wenig präzise Begründungen. | Basale Prüfungen (z. B. Nichtnegativität) vorhanden, aber wichtige Checks fehlen. | Fehlerbehandlung nur ansatzweise; unklare oder fehlende Begründungen. | Keine sinnvollen Validierungen; ungültige Eingaben werden nicht sauber behandelt. |
| Auswertung & Ergebnisdarstellung (evaluate_inventory) | 20 % | Vollständige, klare Ergebnisstruktur (results_df, status_table, priority_product_id, total_reorder_qty) und nachvollziehbare Ausgabe der wichtigsten Ergebnisse. | Ergebnisse überwiegend korrekt; kleine Unschärfen in Struktur oder Ausgabe. | Ergebnisse prinzipiell vorhanden, aber unvollständig oder teils unklar (z. B. fehlende Tabelle oder fehlende Summen). | Ausgabe unsystematisch; zentrale Elemente fehlen; Ergebnisstruktur ist schwer nutzbar. | Keine verwertbare Auswertung. |
| Reproduzierbarkeit (seed, run_inventory, Dateiname) | 10 % | Seed wird korrekt verwendet; run_inventory läuft reproduzierbar; Dateiname und Code sind sauber und ohne absolute, personenabhängige Pfade gehalten. | Seed und Ablauf sind im Wesentlichen reproduzierbar; geringe Reibungen (z. B. kleinere Namens- oder Pfadprobleme). | Reproduzierbarkeit ist teilweise gegeben, aber nicht konsequent umgesetzt oder nur mit zusätzlichem Aufwand nachvollziehbar. | Keine klare Reproduzierbarkeit; seed oder zentraler Ablauf fehlen bzw. sind unklar. | Nicht reproduzierbar. |
Hausarbeit 1
Programmierung in R: Lagerbestand und Nachbestellung
Aufgabe: Lagerbestand und Nachbestellung (10 Punkte)
Ziel
Sie entwickeln ein kleines R-Toolkit zur Auswertung einfacher Lagerbestandsdaten. Dabei prüfen Sie einzelne Produkte auf Plausibilität, berechnen Lagerwerte, bestimmen Nachbestellmengen und werten alle Produkte eines Datensatzes systematisch aus.
Die Aufgabe ist bewusst so formuliert, dass Sie zentrale Inhalte der Vorlesung praktisch anwenden:
- eigene Funktionen
if/else- Schleifen oder
apply-Varianten in Base R - Listen als Rückgabewerte
- Kommentare und sprechende Variablennamen
Nutzen Sie für diese Hausarbeit ausschließlich Base R. Externe Pakete wie dplyr, purrr oder das tidyverse sind nicht erlaubt.
Teil 1 (vorgegeben): Generator
Verwenden Sie ausschließlich die folgende Funktion make_inventory(seed), um die Eingabedaten zu erzeugen. Verändern Sie diese Funktion nicht.
make_inventory <- function(seed) {
set.seed(seed)
n <- 8L
product_names <- c(
"USB-Stick", "Maus", "Tastatur", "Monitor",
"Headset", "Webcam", "Router", "SSD"
)
stock_level <- sample(0:30, size = n, replace = TRUE)
reorder_level <- sample(5:20, size = n, replace = TRUE)
unit_cost <- round(runif(n, min = 3, max = 80), 2)
# Mindestens ein gültiger Nachbestellfall
stock_level[1] <- 2L
reorder_level[1] <- 10L
unit_cost[1] <- 14.50
# Mindestens ein problematischer Fall
stock_level[2] <- -1L
df <- data.frame(
product_id = 1:n,
product_name = product_names,
stock_level = stock_level,
reorder_level = reorder_level,
unit_cost = unit_cost,
stringsAsFactors = FALSE
)
return(df)
}Die Spalten von df haben folgende Bedeutung:
product_id: eindeutige ID des Produktsproduct_name: Produktnamestock_level: aktueller Lagerbestandreorder_level: Meldebestandunit_cost: Stückkosten in Euro
Ihre Aufgabe beginnt ab Teil 2.
Teil 2: Kernfunktionen
In Teil 2 entwickeln Sie die Bausteine für die spätere Gesamtauswertung. Alle folgenden Funktionen arbeiten pro item, also immer nur mit den Werten eines einzelnen Produkts bzw. einer einzelnen Zeile des Datensatzes.
Schreiben Sie diese Funktionen ohne externe Pakete. Verwenden Sie sprechende Parameternamen, sinnvolle Kommentare und Fehlerbehandlung.
Funktion 1: check_item(stock_level, reorder_level, unit_cost)
Zweck: Diese Funktion prüft, ob die Angaben zu einem einzelnen Produkt überhaupt plausibel genug sind, um weitere Berechnungen darauf aufzubauen. Sie dient also als Vorprüfung für die anderen Funktionen.
check_item() soll noch keinen Lagerwert und keine Nachbestellmenge berechnen. Die Funktion entscheidet nur, ob das item gültig ist, und liefert im Fehlerfall eine kurze Begründung.
Rückgabe: Liste mit mindestens
is_valid(TRUE/FALSE)reason(character, kurze Begründung)
Mindestregeln:
- alle Eingaben sind numerisch
- alle Eingaben haben Länge 1
- keine Eingabe ist
NA stock_level >= 0reorder_level >= 0unit_cost > 0
Für einen gültigen Fall darf reason z. B. den Wert "ok" enthalten.
Funktion 2: stock_value(stock_level, unit_cost)
Zweck: Diese Funktion berechnet für ein einzelnes Produkt, wie hoch der aktuelle Lagerwert ist. Sie beantwortet also die Frage: Welchen Geldwert hat der vorhandene Bestand dieses items?
Die Funktion arbeitet ebenfalls pro item, also nur mit stock_level und unit_cost einer einzelnen Zeile.
Rückgabe: Lagerwert eines Produkts als numeric.
Formel: stock_level * unit_cost
Ungültige Eingaben sollen nicht stillschweigend verarbeitet werden. Sie dürfen dafür z. B. eigene Prüfungen verwenden oder die Logik von check_item() konsistent aufgreifen.
Funktion 3: reorder_qty(stock_level, reorder_level, safety_stock = 5L)
Zweck: Diese Funktion berechnet für ein einzelnes Produkt, ob und in welcher Höhe nachbestellt werden sollte. Sie beantwortet also die Frage: Wie viele Einheiten dieses items müssen bestellt werden, damit Meldebestand und Sicherheitsbestand wieder erreicht werden?
Die Funktion arbeitet pro item, also mit den Werten genau einer Zeile.
Dabei gelten die Begriffe in dieser Aufgabe wie folgt:
reorder_level: der Meldebestand; ab dieser Bestandsgröße ist klar, dass nachbestellt werden musssafety_stock: der Sicherheitsbestand; diese zusätzliche Reserve soll nach der Nachbestellung ebenfalls wieder vorhanden sein
In diesem vereinfachten Modell gilt also:
- Solange
stock_level > reorder_level, wird nicht nachbestellt. - Sobald
stock_level <= reorder_level, wird eine Bestellung ausgelöst. - Wenn bestellt wird, soll der Bestand wieder auf
reorder_level + safety_stockangehoben werden.
Das bedeutet: reorder_level ist die Auslöseschwelle der Bestellung, safety_stock ist die zusätzliche Reserve oberhalb dieser Schwelle.
Rückgabe: Nachbestellmenge als ganze Anzahl von Einheiten.
Falls stock_level > reorder_level, soll die Funktion 0 zurückgeben. Falls stock_level <= reorder_level, gilt die Formel reorder_level + safety_stock - stock_level.
Mindestregeln:
stock_level,reorder_levelundsafety_stocksind numerisch- alle Eingaben haben Länge 1
- keine Eingabe ist
NA stock_level >= 0reorder_level >= 0safety_stock >= 0
Die folgenden Beispiele dienen als Orientierung für die erwartete Logik:
stock_value(stock_level = 8, unit_cost = 2.5)
# [1] 20
reorder_qty(stock_level = 4, reorder_level = 10, safety_stock = 5)
# [1] 11
reorder_qty(stock_level = 14, reorder_level = 10, safety_stock = 5)
# [1] 0
check_item(stock_level = -2, reorder_level = 10, unit_cost = 4)$is_valid
# [1] FALSETeil 3: Auswertung über alle Produkte
In Teil 3 bauen Sie aus den drei Einzelfunktionen aus Teil 2 eine Gesamtauswertung für den kompletten Datensatz. evaluate_inventory(df, safety_stock = 5L) soll die Werte aus df zeilenweise verarbeiten und die Funktionen aus Teil 2 systematisch auf alle items anwenden.
Die Idee ist:
- pro Zeile zuerst
check_item(...)ausführen - nur für gültige Zeilen die Funktionen
stock_value(...)undreorder_qty(...)anwenden - alle Ergebnisse in einer gemeinsamen Ergebnisstruktur zusammenführen
Die Funktion soll für jedes Produkt mindestens Folgendes bestimmen:
is_validreasonstock_valuereorder_qtystatus
Die Statuslogik ist vollständig vorgegeben:
"invalid": wenncheck_item(...)$is_validgleichFALSEist"reorder": wenn der Fall gültig ist undreorder_qty > 0"ok": wenn der Fall gültig ist undreorder_qty == 0
Die Rückgabe von evaluate_inventory() ist eine Liste mit genau diesen Elementen:
results_df: Originalspalten plus berechnete Spaltenstatus_table: Anzahl der Produkte je Statuspriority_product_id:product_iddes gültigen Produkts mit der höchsten Nachbestellmengetotal_reorder_qty: Summe aller Nachbestellmengen über gültige Produkte mit Status"reorder"
Zusätzliche Regeln für evaluate_inventory():
- Verwenden Sie Basis-R. Sie dürfen z. B. eine
for-Schleife oder eineapply-Variante nutzen. evaluate_inventory()soll die drei Funktionen aus Teil 2 sichtbar als Bausteine wiederverwenden.priority_product_idsoll bei Gleichstand die kleinsteproduct_idwählen.- Falls es kein gültiges Produkt mit Status
"reorder"gibt, sollpriority_product_idden WertNAerhalten. - Ungültige Produkte sollen in
results_dfbei den berechneten numerischen Spalten mitNAerscheinen.
Eine saubere Lösung ist meist modular aufgebaut: zuerst kleine Funktionen für Einzelberechnungen, danach eine Hauptfunktion für die Auswertung des gesamten Data Frames.
Teil 4: Gesamtablauf mit run_inventory()
Teil 4 bündelt den gesamten Workflow in einer einzigen Funktion. Das ist sinnvoll, weil damit die komplette Bearbeitung von der Datenerzeugung bis zur Ausgabe an einer Stelle nachvollziehbar wird. Außerdem haben Sie damit einen klaren Einstiegspunkt für Tests, Demonstration und Screencast.
Schreiben Sie run_inventory(seed), die
df <- make_inventory(seed)erzeugt,res <- evaluate_inventory(df)ausführt- und anschließend die wichtigsten Ergebnisse übersichtlich ausgibt
Die Ausgabe soll mindestens enthalten:
res$status_tableres$total_reorder_qtyres$priority_product_id- die wichtigsten Kennzahlen des priorisierten Produkts, falls ein solches Produkt existiert
Ein typischer Aufruf soll so aussehen:
run_inventory(seed = 123456)Abgabe
Abgabe folgender Resultate über Teams Assignment bis Montag, 23.03.2026, 23:59 Uhr:
- R-Skript:
inventory_toolkit.Rmit allen Funktionen aus Teil 2 bis Teil 4 - Kurz-Screencast (max. 5 Minuten): kurze Erläuterung Ihres Codes und Live-Aufruf
run_inventory(seed = <Ihre_Matrikelnummer>)1
Bitte achten Sie dabei besonders auf:
- gut lesbare Kommentare
- sprechende Funktions- und Variablennamen
- nachvollziehbare Fehlerbehandlung
- reproduzierbare Ausführung über den
seed
Verwendung von KI-Tools (für diese Aufgabe)
- Grundsätzlich erlaubt, aber unterstützend und reflektiert
- Zuerst selbst lösen, dann ggf. KI gezielt als Hilfestellung einsetzen
- Übernommener Code muss vollständig verstanden und im Video erklärt werden
- Transparenz: Größere KI-Nutzung bitte kurz kenntlich machen (1 bis 2 Sätze)
Bewertungskriterien
