Block_04
Programmanalyselabor¶
-
Was ist ein Container?
-
Ein Container ist eine isolierte Umgebung, die eine Anwendung und alle ihre Abhängigkeiten enthält. Technologien wie Docker ermöglichen, Software in Containern plattformunabhängig und konsistent auszuführen.
-
Was hat das mit einer Superstar-Hochzeit zu tun?
-
In der IT ist dies vermutlich ein metaphorischer Vergleich: Container können beliebige Anwendungen isoliert und organisiert ausführen, ähnlich wie bei einer Hochzeit, bei der jeder Gast seine spezifische Rolle oder Funktion hat, ohne sich gegenseitig zu stören.
-
Wie kann das Programm aktualisiert werden, damit es mit aktuellem Python funktioniert?
-
Updates könnten eine Überprüfung der Bibliotheken, die Anpassung veralteter Funktionen und das Sicherstellen, dass
FERund OpenCV mit der neuesten Python-Version kompatibel sind, beinhalten. Alternativ können modernere Emotionserkennungs-Tools genutzt werden. -
Gibt es Alternativen zur FER-Bibliothek?
-
Ja, Alternativen sind z. B.:
- DeepFace: Bietet Emotionserkennung, Alters- und Geschlechtsschätzung.
- mediapipe: Unterstützt Gesichtserkennung und Analyse.
- dlib: Wird für Gesichtserkennung und -analyse genutzt, kann mit Modellen zur Emotionserkennung erweitert werden.
-
Installation von
cv2undfer:
- pip install opencv-python
- pip install fer
haarcascade.xml:
- Quelle: OpenCV GitHub "https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml") "https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml%22)")
- Ablage: Im Ordner haarcascade_xml/, Pfad im Code anpassen.
- Programmbereiche:
- Gesichtserkennung: cascade.detectMultiScale
- Emotionserkennung: emotion_detector.top_emotion
- Funktionsweise:
- Kamera erfasst Bild → Gesichtserkennung mit Haar-Cascade → Emotionserkennung mit FER.
-
Text für Beenden:
Der Text „Zum Beenden Taste 'q' drücken“ wird am unteren Rand des Bildes angezeigt. -
Emojis für Emotionen:
Zu jeder erkannten Emotion wird ein passendes Emoji hinzugefügt und angezeigt. Emojis wie😊für "happy",😡für "angry", etc., werden je nach Emotion angezeigt. -
Emotionen-Timer:
Ein Timer wird gestartet und zählt die Dauer jeder erkannten Emotion in Sekunden, wobei der Timer zurückgesetzt wird, wenn eine neue Emotion erkannt wird.
Funktionsweise:¶
- Emotionen: Wenn eine Emotion erkannt wird, wird das entsprechende Emoji angezeigt. Der Timer für die Dauer der Emotion beginnt oder wird fortgesetzt.
- Text: Am unteren Bildschirmrand erscheint die Nachricht, dass die Taste 'q' zum Beenden gedrückt werden kann.
- Timer: Der Timer zählt die Zeit, in der die Emotion aktiv ist, und wird bei einer neuen Emotion neu gestartet
1. Fenster schließt sich nicht mit "X"¶
Das liegt daran, dass OpenCV die Schleife weiter ausführt, selbst wenn das "X" geklickt wird. Man muss das Schließen des Fensters zusätzlich abfangen.
import cv2
from fer import FER
import time
# Kamera und Gesichts-Klassifikator
capture = cv2.VideoCapture(0)
cascade = cv2.CascadeClassifier("haarcascade_xml/haarcascade.xml")
# Emotionserkennungs-Objekt
emotion_detector = FER()
# Timer für Emotionen
emotion_timers = {}
# Emojis für Emotionen
emotion_emojis = {
'happy': '😊',
'sad': '😢',
'angry': '😡',
'surprise': '😲',
'fear': '😨',
'disgust': '🤢',
'neutral': '😐'
}
while True:
_, camera = capture.read()
if camera is None:
print("Fehler beim Lesen der Kamera!")
break
camera_gray = cv2.cvtColor(camera, cv2.COLOR_BGR2GRAY)
# Gesichter erkennen
faces = cascade.detectMultiScale(camera_gray)
for x, y, width, height in faces:
# Rechteck um das Gesicht zeichnen
cv2.rectangle(camera, (x, y), (x + width, y + height), color=(0, 0, 255), thickness=5)
# Region des Gesichts ausschneiden
face_region = camera[y:y+height, x:x+width]
# Emotionen im Gesicht erkennen
emotion, score = emotion_detector.top_emotion(face_region)
if emotion and score:
# Emoji zur Emotion hinzufügen
emoji = emotion_emojis.get(emotion, '')
emotion_text = f'{emotion}: {score:.2f} {emoji}'
cv2.putText(camera, emotion_text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# Timer für die Emotion starten oder aktualisieren
current_time = time.time()
if emotion not in emotion_timers:
emotion_timers[emotion] = current_time
else:
duration = round(current_time - emotion_timers[emotion], 2)
cv2.putText(camera, f'Dauer: {duration}s', (x, y + height + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
# Text unten anzeigen: 'Zum Beenden Taste "q" drücken'
cv2.putText(camera, "Zum Beenden Taste 'q' drücken", (10, camera.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# Kameraausgabe anzeigen
cv2.imshow("Kamera", camera)
# Beenden, wenn "q" gedrückt wird
if cv2.waitKey(1) == ord("q"):
break
# Kamera freigeben und Fenster schließen
capture.release()
cv2.destroyAllWindows()
2. Erklärung: **if emotion and score:**¶
Diese Zeile prüft, ob sowohl eine Emotion als auch ein Score (Wahrscheinlichkeit) erkannt wurden. Ohne diese Bedingung würde der Code bei None abstürzen.
3. Objektorientierte Umwandlung¶
Hier ist die objektorientierte Variante:
Sinn der Umwandlung:¶
- Vorteile: Bessere Struktur und Wartbarkeit, Wiederverwendbarkeit der Klasse.
- Nachteile: Für ein einfaches Programm kann es unnötig komplex sein.
Fehler:¶
Bei mir tritt die Fehlermeldung auf, dass moviepy.editor nicht korrekt installiert wurde. Ich habe die Bibliothek bereits mehrfach deinstalliert und wieder installiert, jedoch hat keine der Maßnahmen das Problem behoben. Trotz aller Versuche befinde ich mich weiterhin in der gleichen Situation wie zu Beginn.
Kaffeemaschine objektorientiert¶
Die objektorientierte Umsetzung der Kaffeemaschine führt zu einer übersichtlicheren und modulareren Struktur. Die Funktionen und Daten wurden in der Klasse Kaffeeautomat zusammengefasst. Ressourcen, Menü und Geldbetrag werden nun als Attribute verwaltet, während die Logik durch Methoden wie reichen_ressourcen, verarbeitung_muenzen und kaffee_ausgeben abgedeckt wird.
In der Hauptdatei (main.py) wird eine Instanz der Klasse erstellt, und die Methoden werden genutzt, um Benutzereingaben wie Getränkeauswahl, Statusanzeige oder Ressourcenauffüllung zu verarbeiten.
Vorteile:¶
- Modularität: Einfaches Hinzufügen neuer Funktionen oder Getränke.
- Wartbarkeit: Fehler sind durch die klare Trennung der Funktionalitäten leichter zu beheben.
- Wiederverwendbarkeit: Die Klasse kann in anderen Projekten eingesetzt werden.
- Übersichtlichkeit: Der Code ist robuster, verständlicher und zukunftssicher.
Diese Anpassungen machen die Kaffeemaschine effizienter und leichter erweiterbar.
Ich habe zwei Dateien erstellt: main.py und kaffeemaschine.py:
in main.py:
from kaffeemaschine import Kaffeeautomat
kaffeeautomat = Kaffeeautomat()
eingeschaltet = True
while eingeschaltet:
auswahl = input("Was möchten Sie? Espresso | Latte | Cappuccino | status | off | auffuellen: ").capitalize()
if auswahl == "Off":
eingeschaltet = False
elif auswahl == "Status":
kaffeeautomat.status_anzeigen()
elif auswahl == "Auffuellen":
kaffeeautomat.auffuellen()
elif auswahl in kaffeeautomat.menu:
wahl = kaffeeautomat.menu[auswahl]
print(f"Kosten für {auswahl}: CHF {wahl['preis']:.2f}")
if kaffeeautomat.reichen_ressourcen(wahl["zusammensetzung"]):
bezahlung = kaffeeautomat.verarbeitung_muenzen()
if kaffeeautomat.ist_geld_ausreichend(bezahlung, wahl["preis"]):
kaffeeautomat.kaffee_ausgeben(auswahl)
else:
print("Ungültige Eingabe. Bitte wählen Sie ein gültiges Getränk oder eine Option.")
in kaffeemaschine.py:
class Kaffeeautomat:
def __init__(self):
self.menu = {
"Espresso": {
"zusammensetzung": {
"wasser": 50,
"kaffeebohnen": 18,
},
"preis": 1.5,
},
"Latte": {
"zusammensetzung": {
"wasser": 200,
"milch": 150,
"kaffeebohnen": 24,
},
"preis": 2.5,
},
"Cappuccino": {
"zusammensetzung": {
"wasser": 250,
"milch": 100,
"kaffeebohnen": 24,
},
"preis": 3.0,
}
}
self.ressourcen = {
"wasser": 300,
"milch": 200,
"kaffeebohnen": 100
}
self.geldbetrag = 0
def reichen_ressourcen(self, zusammensetzung):
for item in zusammensetzung:
if zusammensetzung[item] > self.ressourcen.get(item, 0):
print(f"Leider nicht genug {item}.")
return False
return True
def verarbeitung_muenzen(self):
print("Bitte Münzen einwerfen:")
insgesamt = int(input("Wie viele 10-Rappen? ")) * 0.1
insgesamt += int(input("Wie viele 20-Rappen? ")) * 0.2
insgesamt += int(input("Wie viele 50-Rappen? ")) * 0.5
insgesamt += int(input("Wie viele 1-Franken? ")) * 1
insgesamt += int(input("Wie viele 2-Franken? ")) * 2
return insgesamt
def ist_geld_ausreichend(self, geld_erhalten, preis):
if geld_erhalten >= preis:
wechselgeld = round(geld_erhalten - preis, 2)
print(f"Sie erhalten CHF {wechselgeld} zurück.")
self.geldbetrag += preis
return True
else:
print("Das Geld reicht leider nicht aus. Geld wird zurückgegeben.")
return False
def kaffee_ausgeben(self, auswahl):
zusammensetzung = self.menu[auswahl]["zusammensetzung"]
for item in zusammensetzung:
self.ressourcen[item] -= zusammensetzung[item]
print(f"Ihr {auswahl} wird zubereitet. Geniessen Sie Ihren Kaffee ☕")
def auffuellen(self):
self.ressourcen["wasser"] += int(input("Wie viel Wasser hinzufügen? "))
self.ressourcen["milch"] += int(input("Wie viel Milch hinzufügen? "))
self.ressourcen["kaffeebohnen"] += int(input("Wie viele Kaffeebohnen hinzufügen? "))
print("Ressourcen wurden erfolgreich aufgefüllt.")
def status_anzeigen(self):
print(f"Wasser: {self.ressourcen.get('wasser', 0)}ml")
print(f"Milch: {self.ressourcen.get('milch', 0)}ml")
print(f"Kaffeebohnen: {self.ressourcen.get('kaffeebohnen', 0)}g")
print(f"Geld insgesamt eingenommen: CHF {self.geldbetrag:.2f}")
Der gezeigte Code implementiert eine einfache Simulation einer Kaffeemaschine in Python, basierend auf objektorientierter Programmierung.
-
Klassendefinition (
kaffeemaschine.py): -
Die Klasse
Kaffeeautomatverwaltet das Menü, die verfügbaren Ressourcen (Wasser, Milch, Kaffeebohnen) und das eingenommene Geld. - Methoden wie
reichen_ressourcen,verarbeitung_muenzenundkaffee_ausgebensteuern den Betrieb der Kaffeemaschine, indem sie überprüfen, ob genügend Ressourcen vorhanden sind, Münzen verarbeiten und Ressourcen nach Getränkezubereitung anpassen. -
Die Methode
auffuellenerlaubt das Nachfüllen von Ressourcen, undstatus_anzeigengibt den aktuellen Zustand der Maschine aus. -
Hauptprogramm (
main.py): -
Eine Instanz der Klasse wird erstellt, und eine Schleife verarbeitet Benutzereingaben.
- Der Benutzer kann ein Getränk auswählen, den Status der Maschine anzeigen, die Maschine auffüllen oder sie ausschalten.
- Das Programm überprüft die Ressourcen und führt die Münzverarbeitung durch, bevor ein Getränk zubereitet wird.
Insgesamt simuliert der Code den Betrieb einer Kaffeemaschine mit grundlegenden Funktionen wie Getränkeauswahl, Ressourcenmanagement und Geldannahme.