Advanced Programming Techniques - Exam.pdf

Advanced Programming Techniques - Exam
Advanced Programming Techniques - Exam Aufgabe 1) Du arbeitest an einer Software zur Verwaltung von verschiedenen Bankkonten, darunter Girokonten und Sparkonten. Deine Aufgabe ist es, durch die Anwendung von abstrakten Klassen und Interfaces eine stabile und erweiterbare Codebasis zu schaffen. Nutze die bereitgestellten Informationen zu abstrakten Klassen und Interfaces, um die folgende Aufgabenst...

© StudySmarter 2024, all rights reserved.

Advanced Programming Techniques - Exam

Aufgabe 1)

Du arbeitest an einer Software zur Verwaltung von verschiedenen Bankkonten, darunter Girokonten und Sparkonten. Deine Aufgabe ist es, durch die Anwendung von abstrakten Klassen und Interfaces eine stabile und erweiterbare Codebasis zu schaffen. Nutze die bereitgestellten Informationen zu abstrakten Klassen und Interfaces, um die folgende Aufgabenstellung zu bearbeiten.

a)

  • Definiere eine abstrakte Klasse Bankkonto, die die grundlegenden Eigenschaften und Methoden eines Bankkontos beschreibt. Diese Klasse soll eine abstrakte Methode berechneJahreszins() enthalten, die den Jahreszins auf das Kontoguthaben berechnet.

Lösung:

Um die Aufgabe zu lösen, definieren wir eine abstrakte Klasse Bankkonto in Java, die sowohl grundlegende Eigenschaften als auch Methoden eines Bankkontos beschreibt. Diese Klasse wird ebenfalls eine abstrakte Methode berechneJahreszins() haben, die von den Unterklassen implementiert werden muss.

  public abstract class Bankkonto {    private String kontonummer;    private String kontoinhaber;    private double kontostand;     public Bankkonto(String kontonummer, String kontoinhaber, double kontostand) {       this.kontonummer = kontonummer;       this.kontoinhaber = kontoinhaber;       this.kontostand = kontostand;    }     public String getKontonummer() {      return kontonummer;    }    public String getKontoinhaber() {      return kontoinhaber;    }    public double getKontostand() {      return kontostand;    }    public void einzahlen(double betrag) {      if (betrag > 0) {        kontostand += betrag;      }    }     public void abheben(double betrag) {      if (betrag > 0 && betrag <= kontostand) {        kontostand -= betrag;      }    }     public abstract double berechneJahreszins();  }   

b)

  • Erstelle zwei konkrete Klassen Girokonto und Sparkonto, die von der abstrakten Klasse Bankkonto erben. Implementiere die Methode berechneJahreszins() in beiden Klassen. Das Girokonto hat einen festen Zinssatz von 1% und das Sparkonto einen festen Zinssatz von 3%.

Lösung:

Um die Aufgabe zu lösen, erstellen wir die konkreten Klassen Girokonto und Sparkonto, die beide von der abstrakten Klasse Bankkonto erben. In beiden Klassen implementieren wir die Methode berechneJahreszins(), wobei das Girokonto einen festen Zinssatz von 1% und das Sparkonto einen festen Zinssatz von 3% hat.

  public class Girokonto extends Bankkonto {    private static final double ZINSSATZ = 0.01;     public Girokonto(String kontonummer, String kontoinhaber, double kontostand) {      super(kontonummer, kontoinhaber, kontostand);    }     @Override    public double berechneJahreszins() {      return getKontostand() * ZINSSATZ;    }  }   public class Sparkonto extends Bankkonto {    private static final double ZINSSATZ = 0.03;     public Sparkonto(String kontonummer, String kontoinhaber, double kontostand) {      super(kontonummer, kontoinhaber, kontostand);    }     @Override    public double berechneJahreszins() {      return getKontostand() * ZINSSATZ;    }  }   

c)

  • In der Finanzwelt gibt es verschiedene Strategien zur Berechnung von Gebühren. Definiere ein Interface GebuehrenStrategie mit einer Methode berechneGebuehren(double betrag). Erstelle zwei Implementationen dieses Interfaces: PauschalgebuehrenStrategie, die stets eine feste Gebühr von 5 Euro berechnet, und ProzentualeGebuehrenStrategie, die eine Gebühr basierend auf einem Prozentsatz von 2% des Betrags berechnet.

Lösung:

Um diese Aufgabe zu lösen, definieren wir zunächst ein Interface GebuehrenStrategie mit der Methode berechneGebuehren(double betrag). Anschließend implementieren wir zwei Klassen, PauschalgebuehrenStrategie und ProzentualeGebuehrenStrategie, die dieses Interface umsetzen.

  public interface GebuehrenStrategie {    double berechneGebuehren(double betrag);  }   public class PauschalgebuehrenStrategie implements GebuehrenStrategie {    private static final double PAUSCHAL_GEBUEHR = 5.0;     @Override    public double berechneGebuehren(double betrag) {      return PAUSCHAL_GEBUEHR;    }  }   public class ProzentualeGebuehrenStrategie implements GebuehrenStrategie {    private static final double PROZENTUALER_SATZ = 0.02;     @Override    public double berechneGebuehren(double betrag) {      return betrag * PROZENTUALER_SATZ;    }  }   

d)

  • Erweitere die Girokonto und Sparkonto Klassen, um die GebuehrenStrategie Schnittstelle zu verwenden. Die Klasse Girokonto soll die PauschalgebuehrenStrategie verwenden, während die Klasse Sparkonto die ProzentualeGebuehrenStrategie verwenden soll. Schreibe jeweils eine Methode berechneGebuehren(double betrag), die die entsprechende Strategie anwendet und die Gebühren berechnet.

Lösung:

Um die Aufgabe zu lösen, erweitern wir die Klassen Girokonto und Sparkonto, um die GebuehrenStrategie zu verwenden. Dabei fügen wir jeweils ein entsprechendes Attribut und die Methode berechneGebuehren(double betrag) hinzu, die die jeweilige Strategie anwendet.

  public class Girokonto extends Bankkonto {    private static final double ZINSSATZ = 0.01;    private GebuehrenStrategie gebuehrenStrategie;     public Girokonto(String kontonummer, String kontoinhaber, double kontostand) {      super(kontonummer, kontoinhaber, kontostand);      this.gebuehrenStrategie = new PauschalgebuehrenStrategie();    }     @Override    public double berechneJahreszins() {      return getKontostand() * ZINSSATZ;    }     public double berechneGebuehren(double betrag) {      return gebuehrenStrategie.berechneGebuehren(betrag);    }  }   public class Sparkonto extends Bankkonto {    private static final double ZINSSATZ = 0.03;    private GebuehrenStrategie gebuehrenStrategie;     public Sparkonto(String kontonummer, String kontoinhaber, double kontostand) {      super(kontonummer, kontoinhaber, kontostand);      this.gebuehrenStrategie = new ProzentualeGebuehrenStrategie();    }     @Override    public double berechneJahreszins() {      return getKontostand() * ZINSSATZ;    }     public double berechneGebuehren(double betrag) {      return gebuehrenStrategie.berechneGebuehren(betrag);    }  }   

Aufgabe 2)

Angenommen, Du bist Softwareentwickler und arbeitest an einem Projekt für ein Online-Zahlungssystem. Dieses System soll verschiedene Zahlungsarten wie Kreditkarten, PayPal und Kryptowährungen unterstützen. Darüber hinaus soll das System sicherstellen, dass gewisse Kernkomponenten nur einmal instanziiert werden und dass erweiterbare Funktionalitäten nach Bedarf ohne große Codeänderungen hinzugefügt werden können. Um diese Anforderungen zu erfüllen, stehst Du vor der Aufgabe, geeignete Entwurfsmuster zu identifizieren und zu implementieren.

a)

Erkläre, wie das Singleton-Muster angewendet werden kann, um sicherzustellen, dass es nur eine Instanz des Zahlungsgateways gibt. Implementiere den Singleton in Python.

Lösung:

Das Singleton-Muster:

Das Singleton-Muster stellt sicher, dass eine Klasse nur eine einzige Instanz haben kann und bietet einen globalen Zugriffspunkt auf diese Instanz. Dieses Muster wird häufig in Situationen verwendet, in denen genau eine Instanz einer Klasse benötigt wird, um eine koordinierte Aktion durchzuführen. In dem Kontext eines Online-Zahlungssystems kann das Singleton-Muster genutzt werden, um sicherzustellen, dass das Zahlungsgateway nur eine Instanz hat, über die alle Zahlungsanfragen abgewickelt werden.

Implementierung des Singleton in Python:

Hier ist eine einfache Implementierung des Singleton-Musters in Python:

class PaymentGateway:     _instance = None    def __new__(cls, *args, **kwargs):        if not cls._instance:            cls._instance = super(PaymentGateway, cls).__new__(cls, *args, **kwargs)        return cls._instance    def __init__(self):        if not hasattr(self, 'initialized'):            self.initialized = True            self.payment_methods = []            self.setup_gateway()    def setup_gateway(self):        # Beispielhafte Einrichtung des Zahlungsgateways        print('Zahlungsgateway wird eingerichtet...')    def add_payment_method(self, method):        self.payment_methods.append(method)        print(f'Zahlungsmethode {method} hinzugefügt.')    def process_payment(self, method, amount):        if method in self.payment_methods:            print(f'Verarbeite Zahlung von {amount} über {method}.')        else:            print(f'Zahlungsmethode {method} nicht verfügbar.')# Beispielhafte Nutzung des Singleton PaymentGatewaysif __name__ == '__main__':    gateway1 = PaymentGateway()    gateway2 = PaymentGateway()    print(f'gateway1 und gateway2 sind gleich: {gateway1 is gateway2}')    gateway1.add_payment_method('Kreditkarte')    gateway1.process_payment('Kreditkarte', 100)    gateway2.add_payment_method('PayPal')    gateway2.process_payment('PayPal', 250)
  • Erklärung des Codes:
  • __new__ Methode: Diese Methode wird verwendet, um eine neue Instanz der Klasse zu erstellen. Sie überprüft, ob die Instanz bereits existiert. Wenn nicht, wird sie erstellt. Falls doch, wird die existierende Instanz zurückgegeben.
  • __init__ Methode: Diese Methode sorgt dafür, dass einmalige Initialisierungen der Klasse vorgenommen werden. Die Variable initialized stellt sicher, dass die Initialisierung nur einmal durchgeführt wird.
  • add_payment_method: Fügt eine neue Zahlungsmethode hinzu.
  • process_payment: Verarbeitet eine Zahlung mit der angegebenen Methode und dem Betrag.

b)

Beschreibe, wie das Factory-Muster verwendet werden kann, um Instanzen der verschiedenen Zahlungsarten (Kreditkarte, PayPal, Kryptowährung) zu erzeugen. Implementiere eine Factory-Klasse in Python, die die verschiedenen Zahlungsarten erstellt und zurückgibt.

Lösung:

Das Factory-Muster:

Das Factory-Muster ist ein Erzeugungsmuster, das zur Erstellung von Objekten verwendet wird, ohne dass die genaue Klasse des erzeugten Objekts angegeben wird. Dieses Muster stellt eine Schnittstelle bereit, um Objekte einer übergeordneten Klasse oder Schnittstelle zu erzeugen, sodass die Erstellung der Objekte an eine spezifische Factory-Klasse delegiert wird. In einem Online-Zahlungssystem kann das Factory-Muster verwendet werden, um Instanzen der verschiedenen Zahlungsarten wie Kreditkarte, PayPal und Kryptowährung zu erzeugen.

Implementierung einer Factory-Klasse in Python:

Hier ist eine einfache Implementierung des Factory-Musters in Python, um verschiedene Zahlungsarten zu erzeugen:

from abc import ABC, abstractmethod# Basis-Zahlungsmethodeclass PaymentMethod(ABC):    @abstractmethod    def process_payment(self, amount):        pass# Kreditkarteclass CreditCard(PaymentMethod):    def process_payment(self, amount):        print(f'Kreditkartenzahlung von {amount} wird verarbeitet...')# PayPalclass PayPal(PaymentMethod):    def process_payment(self, amount):        print(f'PayPal-Zahlung von {amount} wird verarbeitet...')# Kryptowährungclass CryptoCurrency(PaymentMethod):    def process_payment(self, amount):        print(f'Kryptowährungszahlung von {amount} wird verarbeitet...')# Payment Factoryclass PaymentFactory:    @staticmethod    def create_payment_method(method):        if method == 'Kreditkarte':            return CreditCard()        elif method == 'PayPal':            return PayPal()        elif method == 'Kryptowährung':            return CryptoCurrency()        else:            raise ValueError(f'Unbekannte Zahlungsmethode: {method}')# Beispielhafte Nutzung der PaymentFactoryif __name__ == '__main__':    factory = PaymentFactory()    credit_card_payment = factory.create_payment_method('Kreditkarte')    paypal_payment = factory.create_payment_method('PayPal')    crypto_payment = factory.create_payment_method('Kryptowährung')    credit_card_payment.process_payment(100)    paypal_payment.process_payment(150)    crypto_payment.process_payment(200)
  • Erklärung des Codes:
  • PaymentMethod: Dies ist eine abstrakte Basisklasse für alle Zahlungsarten. Die Methode process_payment ist abstrakt und muss von den abgeleiteten Klassen implementiert werden.
  • CreditCard, PayPal, CryptoCurrency: Dies sind konkrete Implementierungen der Zahlungsarten, die die Methode process_payment jeweils spezifisch implementieren.
  • PaymentFactory: Diese Klasse stellt eine statische Methode create_payment_method bereit, die eine Instanz der gewünschten Zahlungsart basierend auf dem übergebenen Parameter erstellt und zurückgibt.

c)

Erläutere, wie das Adapter-Muster genutzt werden kann, um eine einheitliche Schnittstelle für ein externes Zahlungssystem zu implementieren, das eine andere API verwendet. Zeige anhand einer Python-Implementierung, wie der Adapter geschrieben wird.

Lösung:

Das Adapter-Muster:

Das Adapter-Muster wird verwendet, um die Schnittstelle einer bestehenden Klasse in eine andere Schnittstelle zu übersetzen, die ein anderer Client erwartet. Es ermöglicht Klassen, zusammenzuarbeiten, die ansonsten aufgrund unterschiedlicher Schnittstellen inkompatibel wären. In einem Online-Zahlungssystem kann das Adapter-Muster z.B. verwendet werden, um ein externes Zahlungssystem mit einer anderen API nahtlos in das bestehende System zu integrieren.

Beispiel für das Adapter-Muster:

Angenommen, wir haben ein externes Zahlungssystem, das eine andere API verwendet. Wir möchten dieses System in unser bestehendes Zahlungssystem integrieren, ohne den gesamten Code ändern zu müssen.

Hier ist eine Python-Implementierung des Adapter-Musters:

# Externes Zahlungssystemclass ExternalPaymentSystem:    def make_payment(self, amount):        print(f'Externe Zahlung von {amount} wird verarbeitet...')# Unsere erwartete Schnittstelleclass PaymentMethod(ABC):    @abstractmethod    def process_payment(self, amount):        pass# Adapter für das externe Zahlungssystemclass ExternalPaymentAdapter(PaymentMethod):    def __init__(self, external_payment_system):        self.external_payment_system = external_payment_system    def process_payment(self, amount):        # Anpassung der Methode 'process_payment' an die Methode 'make_payment' des externen Systems        self.external_payment_system.make_payment(amount)# Beispielhafte Nutzung des Adaptersif __name__ == '__main__':    external_system = ExternalPaymentSystem()    adapted_payment = ExternalPaymentAdapter(external_system)    adapted_payment.process_payment(300)
  • Erklärung des Codes:
  • ExternalPaymentSystem: Dies ist das externe Zahlungssystem mit einer anderen API, die eine Methode make_payment hat.
  • PaymentMethod: Dies ist eine abstrakte Basisklasse, die die erwartete Schnittstelle für unser Zahlungssystem definiert. Die Methode process_payment muss von allen abgeleiteten Klassen implementiert werden.
  • ExternalPaymentAdapter: Dies ist der Adapter, der die Schnittstelle des externen Zahlungssystems an die erwartete Schnittstelle anpasst. Die Methode process_payment ruft intern die Methode make_payment des ExternalPaymentSystem auf.

Durch die Verwendung des Adapters können wir das externe Zahlungssystem in unser bestehendes System integrieren, ohne den Rest des Codes anpassen zu müssen. Dadurch wird der Code flexibler und wartbarer.

d)

Angenommen, das System soll dynamisch eine Erweiterung für eine Zahlungsart haben, die spezielle Rabatte auf Transaktionen gewährt. Erkläre, wie das Dekorator-Muster angewendet werden kann, um dieses Feature hinzuzufügen, ohne die bestehende Struktur der Zahlungsart zu ändern. Implementiere diese Erweiterung in Python unter Verwendung des Dekorator-Musters.

Lösung:

Das Dekorator-Muster:

Das Dekorator-Muster wird verwendet, um dynamisch Zusatzfunktionen zu bestehenden Objekten hinzuzufügen, ohne deren Struktur zu verändern. Es bietet eine flexible Alternative zur Unterklasse, um Funktionalitäten zu erweitern. In einem Online-Zahlungssystem kann das Dekorator-Muster angewendet werden, um bestehenden Zahlungsarten spezielle Rabatte hinzuzufügen, ohne die ursprüngliche Implementierung der Zahlungsarten ändern zu müssen.

Beispiel für das Dekorator-Muster:

Wir fügen eine Erweiterung hinzu, die einen Rabatt auf Transaktionen gewährt.

Hier ist eine Python-Implementierung des Dekorator-Musters:

from abc import ABC, abstractmethod# Basis-Zahlungsmethodeclass PaymentMethod(ABC):    @abstractmethod    def process_payment(self, amount):        pass# Kreditkarten-Zahlungsmethodeclass CreditCard(PaymentMethod):    def process_payment(self, amount):        print(f'Kreditkartenzahlung von {amount} wird verarbeitet...')# Dekorator-Basisklasseclass PaymentDecorator(PaymentMethod):    def __init__(self, decorated_payment):        self.decorated_payment = decorated_payment    def process_payment(self, amount):        self.decorated_payment.process_payment(amount)# Spezieller Rabatt Dekoratorclass DiscountDecorator(PaymentDecorator):    def __init__(self, decorated_payment, discount):        super().__init__(decorated_payment)        self.discount = discount    def process_payment(self, amount):        discounted_amount = amount - (amount * self.discount / 100)        print(f'Rabatt von {self.discount}% gewährt! Neuer Betrag: {discounted_amount}')        self.decorated_payment.process_payment(discounted_amount)# Beispielhafte Nutzung des Dekoratorsif __name__ == '__main__':    # Kreditkartenzahlung ohne Rabatt    normal_payment = CreditCard()    normal_payment.process_payment(100)    print('---')    # Kreditkartenzahlung mit 10% Rabatt    discounted_payment = DiscountDecorator(normal_payment, 10)    discounted_payment.process_payment(100)
  • Erklärung des Codes:
  • PaymentMethod: Dies ist eine abstrakte Basisklasse für alle Zahlungsarten. Die Methode process_payment muss von den abgeleiteten Klassen implementiert werden.
  • CreditCard: Dies ist eine konkrete Implementierung der Kreditkarten-Zahlungsart.
  • PaymentDecorator: Dies ist die Basisklasse für Dekoratoren. Sie enthält ein Objekt vom Typ PaymentMethod und delegiert die Methodenaufrufe an dieses Objekt weiter.
  • DiscountDecorator: Dies ist der spezielle Dekorator, der einen Rabatt auf den Betrag berechnet. Er erbt von PaymentDecorator und überschreibt die Methode process_payment, um den Rabatt anzuwenden.

Durch die Verwendung des Dekorator-Musters können wir bestehende Zahlungsarten um neue Funktionalitäten erweitern, ohne ihre ursprüngliche Implementierung zu ändern. Dies macht den Code flexibel und leichter erweiterbar.

Aufgabe 3)

Lambda-Ausdrücke und ClosuresLambda-Ausdrücke sind anonyme Funktionen, die keinen Namen haben und direkt verwendet werden. Ein Lambda-Ausdruck hat die Syntax: (Parameter) => Ausdruck und kann überall dort verwendet werden, wo eine Funktion benötigt wird. Sie sind häufig in höheren Funktionen zu finden. Closures hingegen sind Funktionen, die Zugriff auf die Umgebung haben, in der sie erstellt wurden. Eine Closure speichert Variablen aus ihrer Erzeugungsumgebung. Ein typisches Beispiel für eine Closure ist eine Funktion innerhalb einer anderen Funktion, die auf äußere Variablen zugreifen kann.

a)

A. Erstellung und Verwendung von Lambda-AusdrückenImplementiere eine Funktion in Python, die eine Liste von ganzen Zahlen als Argument nimmt und eine neue Liste zurückgibt, die nur die geraden Zahlen aus der ursprünglichen Liste enthält. Verwende dazu einen Lambda-Ausdruck und die Funktion filter.

def filter_even_numbers(numbers):    return list(filter(lambda x: x % 2 == 0, numbers))# Beispielprint(filter_even_numbers([1, 2, 3, 4, 5, 6]))  # Ausgabe: [2, 4, 6]

Lösung:

Lambda-Ausdrücke und ClosuresLambda-Ausdrücke sind anonyme Funktionen, die keinen Namen haben und direkt verwendet werden. Ein Lambda-Ausdruck hat die Syntax: (Parameter) => Ausdruck und kann überall dort verwendet werden, wo eine Funktion benötigt wird. Sie sind häufig in höheren Funktionen zu finden. Closures hingegen sind Funktionen, die Zugriff auf die Umgebung haben, in der sie erstellt wurden. Eine Closure speichert Variablen aus ihrer Erzeugungsumgebung. Ein typisches Beispiel für eine Closure ist eine Funktion innerhalb einer anderen Funktion, die auf äußere Variablen zugreifen kann.Aufgabe A: Erstellung und Verwendung von Lambda-AusdrückenImplementiere eine Funktion in Python, die eine Liste von ganzen Zahlen als Argument nimmt und eine neue Liste zurückgibt, die nur die geraden Zahlen aus der ursprünglichen Liste enthält. Verwende dazu einen Lambda-Ausdruck und die Funktion filter.

def filter_even_numbers(numbers):    return list(filter(lambda x: x % 2 == 0, numbers))# Beispiel# Ausgabe: [2, 4, 6]print(filter_even_numbers([1, 2, 3, 4, 5, 6]))

b)

B. Verständnis von ClosuresErkläre den folgenden Python-Code und beschreibe, wie die enthaltene Closure funktioniert.

def outer_function(x):    def inner_function(y):        return x + y    return inner_functionadd_five = outer_function(5)print(add_five(3))  # Ausgabe: 8
Diskutiere insbesondere, wie die Closure inner_function Zugriff auf die Variable x hat, die in der outer_function definiert wurde. Nutze mathematische Notationen, um den Mechanismus hinter der Closure zu erklären. Zum Beispiel: Wenn outer_function(x) aufgerufen wird, wird die Variable x in der lokalen Umgebung gespeichert. Die Funktion inner_function(y) ist in der Lage, diese Variable zu referenzieren, auch nachdem outer_function(x) abgeschlossen wurde. Die finalen Operationen für den Rückgabewert von inner_function(y) können als x + y geschrieben werden. Welche Vorteile bietet dieser Mechanismus in der Programmierung?

Lösung:

Lambda-Ausdrücke und ClosuresLambda-Ausdrücke sind anonyme Funktionen, die keinen Namen haben und direkt verwendet werden. Ein Lambda-Ausdruck hat die Syntax: (Parameter) => Ausdruck und kann überall dort verwendet werden, wo eine Funktion benötigt wird. Sie sind häufig in höheren Funktionen zu finden. Closures hingegen sind Funktionen, die Zugriff auf die Umgebung haben, in der sie erstellt wurden. Eine Closure speichert Variablen aus ihrer Erzeugungsumgebung. Ein typisches Beispiel für eine Closure ist eine Funktion innerhalb einer anderen Funktion, die auf äußere Variablen zugreifen kann.Aufgabe B: Verständnis von ClosuresErkläre den folgenden Python-Code und beschreibe, wie die enthaltene Closure funktioniert.

def outer_function(x):    def inner_function(y):        return x + y    return inner_functionadd_five = outer_function(5)print(add_five(3))  # Ausgabe: 8
Diskutiere insbesondere, wie die Closure inner_function Zugriff auf die Variable x hat, die in der outer_function definiert wurde. Nutze mathematische Notationen, um den Mechanismus hinter der Closure zu erklären. Zum Beispiel:
  • Wenn outer_function(x) aufgerufen wird, wird die Variable x in der lokalen Umgebung gespeichert.
  • Die Funktion inner_function(y) ist in der Lage, diese Variable zu referenzieren, auch nachdem outer_function(x) abgeschlossen wurde.
  • Die finalen Operationen für den Rückgabewert von inner_function(y) können als \(x + y\) geschrieben werden.
Welche Vorteile bietet dieser Mechanismus in der Programmierung?Erklärung:Die outer_function(x) ist eine äußere Funktion, die eine innere Funktion inner_function(y) definiert und zurückgibt.
  • Wenn outer_function(5) aufgerufen wird, wird die Variable x auf den Wert 5 gesetzt.
  • Die inner_function(y) nimmt einen Parameter y und gibt den Ausdruck x + y zurück.
Da inner_function in der Umgebung von outer_function erstellt wird, hat sie Zugriff auf die Variable x, die in der äußeren Funktion definiert wurde. Auch nachdem die outer_function beendet wurde, bleibt der Wert von x (in diesem Fall 5) in der Closure gespeichert. Wenn wir nun add_five = outer_function(5) aufrufen, erhalten wir eine Funktion, die inner_function entspricht, wobei x immer noch 5 ist. Wenn wir add_five(3) aufrufen, wird 5 (der gespeicherte Wert von x) zu 3 (dem Wert von y) addiert, was 8 ergibt.Die mathematische Darstellung ist somit:
  • \[\text{{outer_function}}(x) = \text{{inner_function}}(y) = x + y\]
  • \[\text{{add_five}} = \text{{outer_function}}(5)\]
  • \[\text{{add_five}}(3) = 5 + 3 = 8\]
Ein Vorteil dieses Mechanismus ist die Möglichkeit, Funktionen zu erzeugen, die bestimmte Parameter 'merken' können, ohne dass diese Parameter ständig neu übergeben werden müssen. Dies führt zu flexiblerem und modularerem Code.

Aufgabe 4)

Gegeben sei eine Liste von Zahlen:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Du sollst verschiedene höhere Ordnungsfunktionen und lambda-Funktionen verwenden, um diese Liste entsprechend zu verarbeiten.

a)

Schreibe eine Funktion in Python, die mit Hilfe der Funktion map und einer lambda-Funktion jedes Element in der Liste quadriert.

Lösung:

Aufgabe: Liste von Zahlen quadrieren

Gegeben sei eine Liste von Zahlen:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Du sollst eine Funktion in Python schreiben, die mit Hilfe der Funktion map und einer lambda-Funktion jedes Element in der Liste quadriert.

Lösung:

Hier ist eine Python-Funktion, die jedes Element in der Liste quadriert:

def quadriere_liste(liste):    return list(map(lambda x: x**2, liste))# Gegebene Liste von Zahlenzahlenliste = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# Aufruf der Funktion und Ausgabe des Ergebnissesquadrierte_liste = quadriere_liste(zahlenliste)print(quadrierte_liste)
  • Code Erklärung:
  • Die Funktion quadriere_liste nimmt eine Liste als Eingabeargument.
  • Mit map und einer lambda-Funktion wird jedes Element der Liste quadriert.
  • list() wird verwendet, um das Ergebnis von map in eine Liste zu konvertieren.
  • Die quadrierten Elemente werden in quadrierte_liste gespeichert und anschließend ausgegeben.

b)

Verwende die Funktion filter zusammen mit einer lambda-Funktion, um nur die geraden Zahlen aus der Liste herauszufiltern.

Lösung:

Aufgabe: Gerade Zahlen herausfiltern

Gegeben sei eine Liste von Zahlen:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Du sollst mit Hilfe der Funktion filter und einer lambda-Funktion nur die geraden Zahlen aus der Liste herausfiltern.

Lösung:

Hier ist eine Python-Funktion, die nur die geraden Zahlen aus der Liste herausfiltert:

def filter_gerade_zahlen(liste):    return list(filter(lambda x: x % 2 == 0, liste))# Gegebene Liste von Zahlenzahlenliste = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# Aufruf der Funktion und Ausgabe des Ergebnissesgerade_zahlen = filter_gerade_zahlen(zahlenliste)print(gerade_zahlen)
  • Code Erklärung:
  • Die Funktion filter_gerade_zahlen nimmt eine Liste als Eingabeargument.
  • Mit filter und einer lambda-Funktion werden nur die geraden Zahlen aus der Liste herausgefiltert.
  • Die Bedingung x % 2 == 0 prüft, ob eine Zahl gerade ist.
  • list() wird verwendet, um das Ergebnis von filter in eine Liste zu konvertieren.
  • Die geraden Zahlen werden in gerade_zahlen gespeichert und anschließend ausgegeben.

c)

Schreibe eine Funktion in Python, die die Methode reduce aus dem functools-Modul und eine lambda-Funktion verwendet, um die Summe der quadrierten Zahlen der Liste zu berechnen.

Lösung:

Aufgabe: Summe der quadrierten Zahlen berechnen

Gegeben sei eine Liste von Zahlen:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Du sollst eine Funktion in Python schreiben, die die Methode reduce aus dem functools-Modul und eine lambda-Funktion verwendet, um die Summe der quadrierten Zahlen der Liste zu berechnen.

Lösung:

Hier ist eine Python-Funktion, die dies erreichen kann:

from functools import reducedef summe_quadrierter_zahlen(liste):    quadrierte_liste = map(lambda x: x**2, liste)    return reduce(lambda x, y: x + y, quadrierte_liste)# Gegebene Liste von Zahlenzahlenliste = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# Aufruf der Funktion und Ausgabe des Ergebnissessumme = summe_quadrierter_zahlen(zahlenliste)print(summe)
  • Code Erklärung:
  • Die Funktion summe_quadrierter_zahlen nimmt eine Liste als Eingabeargument.
  • Zuerst wird die map-Funktion verwendet, um jedes Element in der Liste zu quadrieren.
  • Die reduce-Funktion wird dann verwendet, um die quadrierten Zahlen zu summieren. Hierbei addiert die lambda-Funktion zwei Elemente nacheinander, um die Gesamtsumme zu berechnen.
  • Die quadrierten Zahlen werden in quadrierte_liste zwischengespeichert, und das Endergebnis der Summation wird in summe gespeichert und anschließend ausgegeben.

d)

Schreibe eine Funktion in Python, die folgende Schritte durchführt:

  • Quadratiere die Elemente der Liste.
  • Filtere die geraden Zahlen heraus.
  • Berechne die Summe dieser gefilterten, quadrierten Zahlen.
Verwende dafür die Funktionen map, filter und reduce in Kombination mit lambda-Funktionen.

Lösung:

Aufgabe: Kombination von höheren Ordnungsfunktionen

Gegeben sei eine Liste von Zahlen:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Du sollst eine Funktion in Python schreiben, die folgende Schritte durchführt:

  • Quadratiere die Elemente der Liste.
  • Filtere die geraden Zahlen heraus.
  • Berechne die Summe dieser gefilterten, quadrierten Zahlen.

Lösung:

Hier ist eine Python-Funktion, die dies erreicht:

from functools import reducedef verarbeite_liste(liste):    # Schritt 1: Quadratiere die Elemente der Liste    quadrierte_liste = map(lambda x: x**2, liste)    # Schritt 2: Filtere die geraden Zahlen heraus    gefilterte_liste = filter(lambda x: x % 2 == 0, quadrierte_liste)    # Schritt 3: Berechne die Summe dieser gefilterten, quadrierten Zahlen    summe = reduce(lambda x, y: x + y, gefilterte_liste)    return summe# Gegebene Liste von Zahlenzahlenliste = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# Aufruf der Funktion und Ausgabe des Ergebnissesergebnis = verarbeite_liste(zahlenliste)print(ergebnis)
  • Code Erklärung:
  • Die Funktion verarbeite_liste nimmt eine Liste als Eingabeargument.
  • Zuerst wird die map-Funktion verwendet, um jedes Element in der Liste zu quadrieren.
  • Anschließend werden mit der filter-Funktion nur die geraden quadrierten Zahlen aus der Liste herausgefiltert.
  • Schließlich wird die reduce-Funktion verwendet, um die gefilterten, quadrierten Zahlen zu summieren. Die lambda-Funktion addiert zwei Elemente nacheinander, um die Gesamtsumme zu berechnen.
  • Das Endergebnis der Summation wird in ergebnis gespeichert und anschließend ausgegeben.
Sign Up

Melde dich kostenlos an, um Zugriff auf das vollständige Dokument zu erhalten

Mit unserer kostenlosen Lernplattform erhältst du Zugang zu Millionen von Dokumenten, Karteikarten und Unterlagen.

Kostenloses Konto erstellen

Du hast bereits ein Konto? Anmelden