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
Arbeitsweise

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.

Listing 1: Funktion zur Erzeugung der Eingabedaten für die Lagerbestandsaufgabe
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 Produkts
  • product_name: Produktname
  • stock_level: aktueller Lagerbestand
  • reorder_level: Meldebestand
  • unit_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 >= 0
  • reorder_level >= 0
  • unit_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 muss
  • safety_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_stock angehoben 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_level und safety_stock sind numerisch
  • alle Eingaben haben Länge 1
  • keine Eingabe ist NA
  • stock_level >= 0
  • reorder_level >= 0
  • safety_stock >= 0
Verbindliche Beispielaufrufe

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] FALSE

Teil 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(...) und reorder_qty(...) anwenden
  • alle Ergebnisse in einer gemeinsamen Ergebnisstruktur zusammenführen

Die Funktion soll für jedes Produkt mindestens Folgendes bestimmen:

  • is_valid
  • reason
  • stock_value
  • reorder_qty
  • status

Die Statuslogik ist vollständig vorgegeben:

  • "invalid": wenn check_item(...)$is_valid gleich FALSE ist
  • "reorder": wenn der Fall gültig ist und reorder_qty > 0
  • "ok": wenn der Fall gültig ist und reorder_qty == 0

Die Rückgabe von evaluate_inventory() ist eine Liste mit genau diesen Elementen:

  • results_df: Originalspalten plus berechnete Spalten
  • status_table: Anzahl der Produkte je Status
  • priority_product_id: product_id des gültigen Produkts mit der höchsten Nachbestellmenge
  • total_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 eine apply-Variante nutzen.
  • evaluate_inventory() soll die drei Funktionen aus Teil 2 sichtbar als Bausteine wiederverwenden.
  • priority_product_id soll bei Gleichstand die kleinste product_id wählen.
  • Falls es kein gültiges Produkt mit Status "reorder" gibt, soll priority_product_id den Wert NA erhalten.
  • Ungültige Produkte sollen in results_df bei den berechneten numerischen Spalten mit NA erscheinen.
Hinweis

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_table
  • res$total_reorder_qty
  • res$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.R mit 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

Tabelle 1: Bewertungskriterien zur Hausarbeit 1
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.

Zurück nach oben

Fußnoten

  1. Für die Aufzeichnung des Videos (Ihr Bildschirm und Ton für die Erläuterungen) können Sie z. B. die kostenlose Version von Loom verwenden.↩︎