Fehlersuche#
Neben der Fehlerbehebung ist es beim Programmieren essentiell Fehler zu finden. Am schwierigsten ist es Fehler zu finden, die Python nicht erkennt, zum Beispiel wenn Sie versehentlich in Ihrer Rechnung \(\texttt{+}\) statt \(\texttt{-}\) geschrieben haben oder die falsche Variable updaten. Augenscheinlich ist Python zufrieden, nur Sie am Ende nicht, da der Code dennoch nicht das tut was Sie wollen 😔. Daher ist es wichtig, dass Sie Ihren Code, insbesondere Funktionen, die Sie schreiben, anhand von kleinen Beispielen testen. Die Beispiele sollten so konstruiert sein, dass Ihnen klar ist was das Ergebnis ist, damit Sie die Ergebnisse vergleichen können. So stellen Sie sicher, dass Ihr Code auch die richtigen Ergenisse erzeugt, wenn die handschriftliche Rechnung zu aufwändig wäre.
Dieses Vorgehen werden wir anhand einer einfachen Aufgabe testen. Dazu erstellen wir eine Funktion, die gewichtete Scores für verschiedene Produkten berechnet. Jedes Produkt hat eine Reihe von Werten, und diese Werte werden mit einem Gewichtsvektor multipliziert, um den Score jedes Produkts zu berechnen. Die Werte umfassen verschiedene Produktmerkmale. Die Produktinformationen sind in der folgenden Tabelle dargestellt:
ID |
Qualität |
Komfort |
Retourenquote |
Leistung |
# Bewertungen |
Lagerbestand |
|---|---|---|---|---|---|---|
1 |
91 |
85 |
30 |
80 |
500 |
1200 |
2 |
80 |
90 |
20 |
85 |
200 |
1500 |
3 |
85 |
80 |
25 |
90 |
1000 |
800 |
4 |
70 |
75 |
40 |
75 |
250 |
500 |
5 |
95 |
90 |
15 |
97 |
400 |
1300 |
6 |
97 |
80 |
35 |
80 |
300 |
1200 |
7 |
80 |
85 |
30 |
85 |
500 |
1400 |
8 |
75 |
78 |
28 |
85 |
350 |
1100 |
9 |
88 |
82 |
32 |
88 |
600 |
1600 |
10 |
76 |
82 |
30 |
80 |
350 |
1100 |
Entsprechend dieser Tabelle ergibt sich die Matrix \(\mathbf{P}\) mit der Sie im folgenden arbeiten werden:
Die Einträge der Matrix \(\mathbf{P}\) sind wie folgt zu verstehen:
Jede Zeile repräsentiert ein Produkt.
Die erste Spalte enthält die Produktnummern.
Die Spalten \(2\) bis \(7\) codieren verschiedene Merkmale des Produkts wie zum Beispiel: Durchschnittsbewertung, Verkaufszahlen, Retourenquote, Preis-Leistungsverhältnis, Anzahl der Bewertungen und Lagerbestand.
Die Gewichtsmatrix, die für die Berechnung des Scores verwendet wird, ist gegeben durch:
Der Score soll basierend auf den normierten Werten berechnet werden, das heißt jedes Merkmal wird durch den maximalen Wert des Merkmals geteilt. Daraus ergibt sich beispielshaft der Score für das erste Produkt
Sie haben bereits einen Codevorschlag erhalten und sollen diesen auf Korrektheit prüfen und gegebenenfalls auftretende Fehler beheben. Zunächst definieren wir aber die entsprechende Matrix \(\mathbf{P}\) als das Array \(\texttt{products}\) und die Gewichte \(\mathbf{w}\) als das Array \(\texttt{weights}\).
import numpy as np
products = np.array([
[1, 91, 85, 30, 80, 500, 1200],
[2, 80, 90, 20, 85, 200, 1500],
[3, 85, 80, 25, 90, 1000, 800],
[4, 70, 75, 40, 75, 250, 500],
[5, 95, 90, 15, 97, 400, 1300],
[6, 97, 80, 35, 80, 300, 1200],
[7, 80, 85, 30, 85, 500, 1400],
[8, 75, 78, 28, 85, 350, 1100],
[9, 88, 82, 32, 88, 600, 1600],
[10, 76, 82, 30, 80, 350, 1100]
], dtype=float)
# Gewichtungen (für jedes Merkmal)
weights = np.array([0.4, 0.25, -0.15, 0.15, 0.05, 0.05])
Testen Sie zunächst, ob der Code für das erste Produkt mit den ersten drei Merkmalen richtig funktioniert. Passen Sie den Code eventuell so an, dass der Score für dieses Produkt richtig berechnet wird.
Wiederholen Sie das Vorgehen mit den ersten zwei Produkten und den ersten drei Merkmalen. Korrigieren Sie den Code, sodass er für dieses Beispiel korrekt funktioniert.
Testen Sie nun die ersten beiden Produkte mit allen Merkmalen. Fällt Ihnen noch ein Fehler auf? Falls ja, beheben Sie diesen. Danach können Sie alle Produkte als Eingabe für die Funktion ausprobieren.
def score_berechnung(P, w):
"""
Berechnet die gewichteten Scores für Produkte.
EINGABE:
- P: numpy Array mit Produktinformationen (erste Spalte sind Nummern, restliche Spalten sind Merkmale)
- w: numpy Array mit Gewichtungen für jedes Merkmal
AUSGABE:
- scores: numpy Array mit Produktnummern und gewichteten Scores
"""
ids = P[:, 0] # Produktnummern
values = P[:, 1:] # Merkmale
# Normalisierung der Merkmale
for i in range(values.shape[1]):
values[:, i] = values[:, i] / values[:, i]
# Berechnung der Scores mit einer Schleife
scores = np.zeros(len(ids))
for i in range(1):
for j in range(len(w)):
scores[i] = scores[i] + values[i, j] * w[i]
# Kombiniere Produktnummern mit Scores
product_scores = np.column_stack((ids, scores))
return product_scores
# Ihr Code
product_scores = score_berechnung(....) # hier Test-Daten übergeben
# Ausgabe der Produktnummern und Scores
for product, score in product_scores:
print(f"Produkt {int(product)}: {score:.2f}")
Hinweis A1.1
Wurden alle Indizes richtig gesetzt?
Hinweis A1.2
Bei der Normierung werden für unterschiedliche Produkte durch unterschiedliche Werte geteilt. Ist das sinnvoll? Laufen die Schleifen über die richtigen Werte?
Lösung A1.1
def score_berechnung(P, w):
"""
Berechnet die gewichteten Scores für Produkte.
EINGABE:
- P: numpy Array mit Produktinformationen (erste Spalte sind Nummern, restliche Spalten sind Merkmale)
- w: numpy Array mit Gewichtungen für jedes Merkmal
AUSGABE:
- scores: numpy Array mit Produktnummern und gewichteten Scores
"""
ids = P[:, 0]
values = P[:, 1:]
for i in range(values.shape[1]):
values[:, i] = values[:, i] / values[:, i]
scores = np.zeros(len(ids))
for i in range(1):
for j in range(len(w)):
scores[i] = scores[i] + values[i, j] * w[j] # Korrektur
product_scores = np.column_stack((ids, scores))
return product_scores
# Beispiel-Daten für die ersten 3 Merkmale
products_test = products[0:1, :4].copy()
weights_test = weights[:3].copy()
product_scores = score_berechnung(products_test, weights_test)
# Ausgabe der Produktnummern und Scores
for product, score in product_scores:
print(f"Produkt {int(product)}: {score:.2f}")
Lösung A1.2
def score_berechnung(P, w):
"""
Berechnet die gewichteten Scores für Produkte.
EINGABE:
- P: numpy Array mit Produktinformationen (erste Spalte sind Nummern, restliche Spalten sind Merkmale)
- w: numpy Array mit Gewichtungen für jedes Merkmal
AUSGABE:
- scores: numpy Array mit Produktnummern und gewichteten Scores
"""
ids = P[:, 0]
values = P[:, 1:]
for i in range(values.shape[1]):
values[:, i] = values[:, i] / np.max(values[:, i]) # Korrektur
scores = np.zeros(len(ids))
for i in range(len(ids)): # Korrektur
for j in range(len(w)):
scores[i] = scores[i] + values[i, j] * w[j] # Korrektur A1.1
product_scores = np.column_stack((ids, scores))
return product_scores
# Beispiel-Daten
products_test = products[0:2, :4].copy()
weights_test = weights[:3].copy()
product_scores = score_berechnung(products_test, weights_test)
# Ausgabe der Produktnummern und Scores
for product, score in product_scores:
print(f"Produkt {int(product)}: {score:.2f}")
Lösung A2.3
def score_berechnung(P, w):
"""
Berechnet die gewichteten Scores für Produkte.
EINGABE:
- P: numpy Array mit Produktinformationen (erste Spalte sind Nummern, restliche Spalten sind Merkmale)
- w: numpy Array mit Gewichtungen für jedes Merkmal
AUSGABE:
- scores: numpy Array mit Produktnummern und gewichteten Scores
"""
ids = P[:, 0]
values = P[:, 1:]
for i in range(values.shape[1]):
values[:, i] = values[:, i] / np.max(values[:, i]) # Korrektur A1.2
scores = np.zeros(len(ids))
for i in range(len(ids)): # Korrektur A1.2
for j in range(len(w)):
scores[i] = scores[i] + values[i, j] * w[j] # Korrektur A1.1
product_scores = np.column_stack((ids, scores))
return product_scores
# Beispiel-Daten
products_test = products.copy()
weights_test = weights.copy()
product_scores = score_berechnung(products_test, weights_test)
# Ausgabe der Produktnummern und Scores
for product, score in product_scores:
print(f"Produkt {int(product)}: {score:.2f}")