Python
Mastering Python's Histogram: A Beginner's Guide

Meisterung von Pythons Histogramm: Ein Leitfaden für Anfänger

[![MoeNagy Dev] (https://raw.githubusercontent.com/lynn-mikami/Images/main/moenagy-dev.png (opens in a new tab))] (/)

Die Histogrammfunktion

Das Histogramm verstehen: Definition und Zweck

Ein Histogramm ist eine graphische Darstellung der Verteilung eines Datensatzes. Es ist ein grundlegendes Werkzeug in der Datenvisualisierung und der explorativen Datenanalyse, da es wertvolle Einblicke in die zugrunde liegenden Muster und Merkmale eines Datensatzes liefert.

Das Histogramm wird erstellt, indem der Datenbereich in eine Reihe von gleichgroßen Bins oder Intervallen unterteilt wird und dann die Anzahl der Datenpunkte gezählt wird, die in jeden Bin fallen. Das resultierende Diagramm zeigt die Häufigkeit oder Anzahl der Datenpunkte in jedem Bin an und ermöglicht Ihnen somit die Visualisierung der Form und Verteilung der Daten.

Histogramme sind besonders nützlich für:

  • Identifizierung des zentralen Tendenz und der Streuung eines Datensatzes
  • Erkennung von Schiefe, Symmetrie und dem Vorhandensein mehrerer Modi
  • Identifizierung von Ausreißern und Anomalien
  • Vergleich der Verteilungen mehrerer Datensätze

Hauptmerkmale und Anwendungen von Histogrammen

Das Histogramm ist ein vielseitiges Werkzeug, das auf eine Vielzahl von Datenanalyseaufgaben angewendet werden kann. Einige der Hauptmerkmale und Anwendungen von Histogrammen sind:

  1. Visualisierung von Datenverteilungen: Histogramme bieten eine klare und intuitive Möglichkeit, die Verteilung eines Datensatzes zu visualisieren, sodass Sie Muster, Trends und Anomalien identifizieren können.

  2. Deskriptive Statistik: Histogramme können verwendet werden, um verschiedene deskriptive Statistiken zu berechnen und zu visualisieren, wie den Durchschnitt, den Median, den Modus und die Standardabweichung, die für das Verständnis der Merkmale eines Datensatzes entscheidend sind.

  3. Wahrscheinlichkeitsdichteschätzung: Histogramme können verwendet werden, um die Wahrscheinlichkeitsdichtefunktion (PDF) einer kontinuierlichen Zufallsvariable abzuschätzen, was insbesondere in der Wahrscheinlichkeits- und Statistikmodellierung nützlich ist.

  4. Vergleich von Verteilungen: Histogramme können verwendet werden, um die Verteilungen mehrerer Datensätze zu vergleichen, was für Aufgaben wie Marktsegmentierung, Anomalieerkennung und A/B-Tests wertvoll ist.

  5. Merkmalsextraktion und -auswahl: Histogramme können verwendet werden, um die Verteilung einzelner Merkmale in einem Datensatz zu analysieren, was Entscheidungen zur Merkmalsextraktion und -auswahl in maschinellem Lernen und Datenanalyse informieren kann.

  6. Ausreißererkennung: Histogramme können verwendet werden, um Ausreißer und Anomalien in einem Datensatz zu identifizieren, was für die Datenbereinigung, die Betrugserkennung und andere Anwendungen wichtig ist.

  7. Hypothesentest: Histogramme können verwendet werden, um die Verteilung von Teststatistiken zu visualisieren, was für die Durchführung von statistischen Hypothesentests und das Ziehen von Schlussfolgerungen über die zugrunde liegende Population wesentlich ist.

Durch das Verständnis der Hauptmerkmale und Anwendungen von Histogrammen können Sie dieses leistungsstarke Werkzeug nutzen, um wertvolle Erkenntnisse zu gewinnen und informierte Entscheidungen in einer Vielzahl von Datenanalyse- und Visualisierungsaufgaben zu treffen.

Generieren von Histogrammen in Python

Zur Erzeugung von Histogrammen in Python können verschiedene Bibliotheken wie Matplotlib, Seaborn und Pandas verwendet werden. In diesem Tutorial konzentrieren wir uns auf die Verwendung von Matplotlib, da es eine weit verbreitete und flexible Bibliothek für die Datenvisualisierung ist.

Importieren der erforderlichen Bibliotheken

Um loszulegen, müssen Sie die erforderlichen Bibliotheken importieren:

import numpy as np
import matplotlib.pyplot as plt

Generieren eines grundlegenden Histogramms

Angenommen, Sie haben einen Datensatz numerischer Werte, die in einem NumPy-Array data gespeichert sind. Sie können ein grundlegendes Histogramm mit der Funktion plt.hist() generieren:

# Generieren Sie einige Beispieldaten
data = np.random.normal(0, 1, 1000)
 
# Erstellen Sie ein grundlegendes Histogramm
plt.hist(data, bins=30)
plt.xlabel('Wert')
plt.ylabel('Häufigkeit')
plt.title('Histogramm der Daten')
plt.show()

In diesem Beispiel generieren wir 1000 Zufallszahlen aus einer Standardnormalverteilung und erstellen dann ein Histogramm mit 30 Bins, um die Verteilung der Daten zu visualisieren.

Anpassen des Histogramms: Anpassen der Binsgröße und des Aussehens

Sie können das Aussehen des Histogramms weiter anpassen, indem Sie die Anzahl der Bins, die Binsgröße und andere visuelle Eigenschaften anpassen:

# Anpassen der Anzahl der Bins
plt.figure(figsize=(8, 6))
plt.hist(data, bins=20, edgecolor='black')
plt.xlabel('Wert')
plt.ylabel('Häufigkeit')
plt.title('Histogramm mit 20 Bins')
plt.show()
 
# Anpassen der Binsgröße
plt.figure(figsize=(8, 6))
plt.hist(data, bins=np.arange(-4, 4, 0.5), edgecolor='black')
plt.xlabel('Wert')
plt.ylabel('Häufigkeit')
plt.title('Histogramm mit benutzerdefinierten Bin-Größen')
plt.show()

Im ersten Beispiel passen wir die Anzahl der Bins auf 20 an, und im zweiten Beispiel verwenden wir eine benutzerdefinierte Binsgröße von 0,5, um ein detaillierteres Histogramm zu erstellen.

Erkunden von Datenverteilungen mit Histogrammen

Histogramme sind nicht nur nützlich für die Visualisierung von Daten, sondern auch für das Verständnis der zugrunde liegenden Verteilung der Daten. Durch Analyse der Form und Merkmale eines Histogramms können Sie wertvolle Erkenntnisse über den Datensatz gewinnen.

Identifizierung von Schiefe und Symmetrie

Die Form des Histogramms kann wichtige Informationen über die Verteilung der Daten liefern. Zum Beispiel deutet ein symmetrisches Histogramm auf eine symmetrische Verteilung hin, während ein schiefes Histogramm darauf hindeutet, dass die Daten nach links oder rechts verzerrt sind.

# Generieren eines linksschiefen Datensatzes
left_skewed_data = np.random.lognormal(0, 1, 1000)
 
# Generieren eines rechtsschiefen Datensatzes
right_skewed_data = np.random.chisquare(3, 1000)
 
# Plotten der Histogramme
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.hist(left_skewed_data, bins=30, edgecolor='black')
plt.title('Linksschiefe Verteilung')
 
plt.subplot(1, 2, 2)
plt.hist(right_skewed_data, bins=30, edgecolor='black')
plt.title('Rechtsschiefe Verteilung')
 
plt.show()

In diesem Beispiel generieren wir einen linksschiefen Datensatz aus einer Lognormalverteilung und einen rechtsschiefen Datensatz aus einer Chi-Quadrat-Verteilung. Wir erstellen Histogramme für beide Verteilungen, um die Schiefe zu veranschaulichen.

plt.hist(right_skewed_data, bins=30, edgecolor='black')
plt.title('Rechtssteil verteilt')
plt.show()

In diesem Beispiel generieren wir zwei Datensätze mit unterschiedlichen Schiefe-Eigenschaften und visualisieren sie mithilfe von Histogrammen. Die linkssteil verteilten Daten haben einen längeren Schwanz auf der linken Seite, während die rechtssteil verteilten Daten einen längeren Schwanz auf der rechten Seite haben.

Erkennen von Ausreißern und Anomalien

Histogramme können auch verwendet werden, um Ausreißer und Anomalien in einem Datensatz zu identifizieren. Ausreißer erscheinen in der Regel als Datenpunkte, die außerhalb der Hauptverteilung liegen, oft in den Schwänzen des Histogramms.

# Generieren eines Datensatzes mit Ausreißern
data_with_outliers = np.concatenate([np.random.normal(0, 1, 900), np.random.normal(5, 1, 100)])
 
# Histogramm plotten
plt.figure(figsize=(8, 6))
plt.hist(data_with_outliers, bins=30, edgecolor='black')
plt.xlabel('Wert')
plt.ylabel('Häufigkeit')
plt.title('Histogramm mit Ausreißern')
plt.show()

In diesem Beispiel erzeugen wir einen Datensatz mit 900 normalverteilten Datenpunkten und 100 Ausreißern mit einem Durchschnitt von 5. Das Histogramm zeigt deutlich das Vorhandensein dieser Ausreißer als Datenpunkte im rechten Schwanz der Verteilung.

Vergleich mehrerer Verteilungen

Histogramme können auch dazu verwendet werden, die Verteilungen mehrerer Datensätze zu vergleichen, was für Aufgaben wie Marktsegmentierung, A/B-Tests und Anomalieerkennung nützlich ist.

# Generieren von zwei Datensätzen mit unterschiedlichen Verteilungen
dataset1 = np.random.normal(0, 1, 1000)
dataset2 = np.random.normal(2, 1.5, 1000)
 
# Histogramme nebeneinander plotten
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.hist(dataset1, bins=30, edgecolor='black')
plt.title('Datensatz 1')
 
plt.subplot(1, 2, 2)
plt.hist(dataset2, bins=30, edgecolor='black')
plt.title('Datensatz 2')
plt.show()

In diesem Beispiel erzeugen wir zwei Datensätze mit unterschiedlichen Mittelwerten und Standardabweichungen und plotten ihre Histogramme nebeneinander. Dadurch können wir die Verteilungen der beiden Datensätze visuell vergleichen und etwaige Unterschiede in ihren Eigenschaften erkennen.

Fortgeschrittene Histogramm-Techniken

Obwohl das grundlegende Histogramm ein leistungsfähiges Werkzeug ist, gibt es verschiedene fortgeschrittene Techniken, die Ihre Datenanalyse- und Visualisierungsmöglichkeiten erweitern können.

Normalisierte Histogramme: Visualisierung der Wahrscheinlichkeitsdichte

Eine fortgeschrittene Technik ist das normalisierte Histogramm, das die Wahrscheinlichkeitsdichtefunktion (PDF) der Daten anstelle der Rohhäufigkeiten anzeigt. Dies ist besonders nützlich, wenn man die Verteilungen von Datensätzen mit unterschiedlichen Stichprobengrößen vergleicht.

# Generieren von zwei Datensätzen mit unterschiedlichen Verteilungen
dataset1 = np.random.normal(0, 1, 1000)
dataset2 = np.random.lognormal(0, 1, 1000)
 
# Normalisierte Histogramme plotten
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.hist(dataset1, bins=30, density=True, edgecolor='black')
plt.title('Normalisiertes Histogramm von Datensatz 1')
 
plt.subplot(1, 2, 2)
plt.hist(dataset2, bins=30, density=True, edgecolor='black')
plt.title('Normalisiertes Histogramm von Datensatz 2')
plt.show()

In diesem Beispiel erzeugen wir zwei Datensätze mit unterschiedlichen Verteilungen (normalverteilt und lognormalverteilt) und plotten ihre normalisierten Histogramme. Das Argument density=True in der plt.hist()-Funktion stellt sicher, dass die y-Achse die Wahrscheinlichkeitsdichte anstelle der Rohhäufigkeit darstellt.

Überlagerung von Verteilungen zum Vergleich

Eine andere fortgeschrittene Technik besteht darin, die Histogramme mehrerer Datensätze auf einem einzigen Diagramm zu überlagern, um einen direkten visuellen Vergleich ihrer Verteilungen zu ermöglichen.

# Generieren von zwei Datensätzen mit unterschiedlichen Verteilungen
dataset1 = np.random.normal(0, 1, 1000)
dataset2 = np.random.lognormal(0, 1, 1000)
 
# Histogramme überlagern
plt.figure(figsize=(8, 6))
plt.hist(dataset1, bins=30, density=True, alpha=0.5, label='Datensatz 1')
plt.hist(dataset2, bins=30, density=True, alpha=0.5, label='Datensatz 2')
plt.legend()
plt.xlabel('Wert')
plt.ylabel('Wahrscheinlichkeitsdichte')
plt.title('Überlagerte Histogramme zweier Datensätze')
plt.show()

In diesem Beispiel erzeugen wir zwei Datensätze und plotten ihre Histogramme auf derselben Abbildung. Dabei verwenden wir den Parameter alpha, um die Histogramme halbtransparent zu machen, und den Parameter label, um eine Legende hinzuzufügen. Dadurch können wir die Verteilungen der beiden Datensätze visuell vergleichen.

Kombination von Histogrammen mit anderen Visualisierungstechniken

Histogramme können auch mit anderen Visualisierungstechniken wie Streudiagrammen oder Boxplots kombiniert werden, um ein umfassenderes Verständnis der Daten zu ermöglichen.

# Erzeugen eines Datensatzes mit zwei Merkmalen
X = np.random.normal(0, 1, (1000, 2))
 
# Streudiagramm und Histogramm plotten
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1])
plt.title('Streudiagramm')
 
plt.subplot(1, 2, 2)
plt.hist(X[:, 0], bins=30, edgecolor='black')
plt.hist(X[:, 1], bins=30, edgecolor='black')
plt.title('Histogramme der beiden Merkmale')
plt.show()

In diesem Beispiel erzeugen wir einen Datensatz mit zwei Merkmalen und plotten ein Streudiagramm sowie ein Histogramm nebeneinander, um die Verteilungen der beiden Merkmale zu visualisieren.

Durch die Beherrschung dieser fortgeschrittenen Histogrammtechniken können Sie noch leistungsfähigere Datenanalyse- und Visualisierungsmöglichkeiten in Ihren Python-Projekten nutzen.

Funktionen

Funktionen sind wiederverwendbare Codeblöcke, die eine bestimmte Aufgabe ausführen. Sie können Eingabeparameter enthalten, eine Operation durchführen und einen Wert zurückgeben. Hier ist ein Beispiel für eine einfache Funktion, die zwei Zahlen addiert:

def add_numbers(a, b):
    """
    Addiert zwei Zahlen und gibt das Ergebnis zurück.
 
    Args:
        a (int oder float): Die erste Zahl zur Addition.
        b (int oder float): Die zweite Zahl zur Addition.
 
    Returns:
        int oder float: Die Summe der beiden Zahlen.
    """
    result = a + b
    return result
 
# Verwendung
x = 5
y = 10
sum_of_x_and_y = add_numbers(x, y)
print(sum_of_x_and_y)  # Ausgabe: 15

In diesem Beispiel nimmt die add_numbers-Funktion zwei Argumente, a und b, entgegen und gibt ihre Summe zurück. Die Funktion enthält auch einen Docstring, der eine kurze Beschreibung der Funktion sowie ihrer Parameter und des Rückgabewerts enthält.

Sie können auch Funktionen mit Standardparameterwerten und variabler Argumentanzahl definieren:

def greet(name, greeting="Hallo"):
    """
    Begrüßt eine Person mit der angegebenen Begrüßung.
 
    Args:
        name (str): Der Name der zu begrüßenden Person.
        greeting (str, optional): Die zu verwendende Begrüßung. Standardwert ist "Hallo".
 
    Returns:
        str: Die Begrüßungsnachricht.
    """
    message = f"{greeting}, {name}!"
    return message
 
# Verwendung
print(greet("Alice"))  # Ausgabe: Hallo, Alice!
print(greet("Bob", "Hi"))  # Ausgabe: Hi, Bob!

In diesem Beispiel hat die greet-Funktion einen Standardparameterwert für greeting, was bedeutet, dass der Standardwert von "Hallo" verwendet wird, wenn kein Wert für greeting angegeben wird.

Funktionen können auch eine variable Anzahl von Argumenten mit der *args-Syntax akzeptieren:

def calculate_average(*numbers):
    """
    Berechnet den Durchschnitt der angegebenen Zahlen.
 
    Args:
        *numbers (float): Die Zahlen, von denen der Durchschnitt berechnet werden soll.
 
    Returns:
        float: Der Durchschnitt der angegebenen Zahlen.
    """
    total = sum(numbers)
    num_numbers = len(numbers)
    average = total / num_numbers
    return average
 
# Verwendung
print(calculate_average(5, 10, 15))  # Ausgabe: 10.0
print(calculate_average(2, 4, 6, 8, 10))  # Ausgabe: 6.0

In diesem Beispiel kann die calculate_average-Funktion eine beliebige Anzahl von Argumenten akzeptieren, die in dem Tupel numbers gesammelt werden. Die Funktion berechnet dann den Durchschnitt der angegebenen Zahlen und gibt das Ergebnis zurück.

Module und Pakete

Die Standardbibliothek von Python enthält eine Vielzahl von Modulen, die verschiedene Funktionen bieten, von der Arbeit mit Dateien und Verzeichnissen bis hin zur Durchführung mathematischer Operationen. Sie können auch Ihre eigenen Module und Pakete erstellen, um Ihren Code zu organisieren und wiederverwendbar zu machen.

Hier ist ein Beispiel, wie Sie ein benutzerdefiniertes Modul erstellen und verwenden:

# my_module.py
def greet(name):
    """
    Begrüßt eine Person.
 
    Args:
        name (str): Der Name der zu begrüßenden Person.
 
    Returns:
        str: Die Begrüßungsnachricht.
    """
    return f"Hallo, {name}!"
 
def calculate_area(length, width):
    """
    Berechnet die Fläche eines Rechtecks.
 
    Args:
        length (float): Die Länge des Rechtecks.
        width (float): Die Breite des Rechtecks.
 
    Returns:
        float: Die Fläche des Rechtecks.
    """
    return length * width
# main.py
import my_module
 
print(my_module.greet("Alice"))  # Ausgabe: Hallo, Alice!
print(my_module.calculate_area(5, 10))  # Ausgabe: 50.0

In diesem Beispiel erstellen wir ein benutzerdefiniertes Modul namens my_module.py, das zwei Funktionen definiert: greet und calculate_area. Wir importieren dann das Modul my_module in der Datei main.py und verwenden die darin definierten Funktionen.

Sie können auch Pakete erstellen, die Sammlungen von verwandten Modulen sind. Hier ist ein Beispiel, wie Sie ein einfaches Paket erstellen:

my_package/
    __init__.py
    math_utils.py
    string_utils.py
# my_package/math_utils.py
def add_numbers(a, b):
    return a + b
 
def subtract_numbers(a, b):
    return a - b
# my_package/string_utils.py
def capitalize_string(text):
    return text.capitalize()
 
def reverse_string(text):
    return text[::-1]
# main.py
from my_package import math_utils, string_utils
 
print(math_utils.add_numbers(5, 10))  # Ausgabe: 15
print(math_utils.subtract_numbers(15, 5))  # Ausgabe: 10
print(string_utils.capitalize_string("hello"))  # Ausgabe: Hello
print(string_utils.reverse_string("world"))  # Ausgabe: dlrow

In diesem Beispiel erstellen wir ein Paket namens my_package, das zwei Module enthält: math_utils.py und string_utils.py. Die Datei __init__.py ist eine leere Datei, die Python mitteilt, dass das Verzeichnis ein Paket ist. In der Datei main.py importieren wir die Module math_utils und string_utils aus dem Paket my_package und verwenden die darin definierten Funktionen.

Datei I/O

Python bietet mehrere Funktionen und Methoden zum Arbeiten mit Dateien, einschließlich Lesen aus und Schreiben in Dateien. Hier ist ein Beispiel, wie Sie aus einer Datei lesen und in sie schreiben:

# In eine Datei schreiben
with open("beispiel.txt", "w") as file:
    file.write("Hallo, Welt!")
 
# Aus einer Datei lesen
with open("beispiel.txt", "r") as file:
    content = file.read()
    print(content)  # Ausgabe: Hallo, Welt!

In diesem Beispiel verwenden wir die Funktion open, um eine Datei namens beispiel.txt im Schreibmodus ("w") zu öffnen und den String "Hallo, Welt!" in die Datei zu schreiben. Anschließend öffnen wir dieselbe Datei im Lese-Modus ("r") und lesen ihren Inhalt, den wir auf der Konsole ausgeben.

Die with-Anweisung wird verwendet, um sicherzustellen, dass die Datei ordnungsgemäß geschlossen wird, wenn wir damit fertig sind, auch wenn eine Ausnahme auftritt.

Sie können Dateien auch zeilenweise lesen und schreiben:

# Zeilenweise in eine Datei schreiben
with open("beispiel.txt", "w") as file:
    file.write("Zeile 1\n")
    file.write("Zeile 2\n")
    file.write("Zeile 3\n")
 
# Zeilenweise aus einer Datei lesen
with open("beispiel.txt", "r") as file:
    for line in file:
        print(line.strip())
# Ausgabe:
# Zeile 1
# Zeile 2
# Zeile 3

In diesem Beispiel schreiben wir drei Zeilen in die Datei beispiel.txt und lesen dann die Datei zeilenweise und geben jede Zeile auf der Konsole aus.

Sie können auch die Methode readlines() verwenden, um alle Zeilen einer Datei auf einmal zu lesen und sie in einer Liste zu speichern:

with open("beispiel.txt", "r") as file:
    lines = file.readlines()
    for line in lines:
        print(line.strip())
# Ausgabe:
# Zeile 1
# Zeile 2
# Zeile 3

Ausnahmen

Exceptions sind Ereignisse, die während der Ausführung eines Programms auftreten und den normalen Ablauf der Anweisungen des Programms stören. Python bietet einen integrierten Mechanismus zur Ausnahmebehandlung, der es Ihnen ermöglicht, diese Ausnahmen vorherzusehen und zu behandeln.

Hier ist ein Beispiel, wie man eine Ausnahme behandelt:

try:
    result = 10 / 0  # Dies wird einen ZeroDivisionError auslösen
except ZeroDivisionError:
    print("Fehler: Division durch Null")
else:
    print(f"Ergebnis: {result}")
finally:
    print("Dieser Block wird immer ausgeführt")

In diesem Beispiel versuchen wir, 10 durch 0 zu teilen, was einen ZeroDivisionError auslöst. Wir fangen diese Ausnahme mit dem except-Block ab und geben eine Fehlermeldung aus. Der else-Block wird nur ausgeführt, wenn keine Ausnahme auftritt, und der finally-Block wird immer ausgeführt, unabhängig davon, ob eine Ausnahme auftritt oder nicht.

Sie können auch Ihre eigenen Ausnahmen mit der raise-Anweisung auslösen:

def divide_numbers(a, b):
    if b == 0:
        raise ValueError("Kann nicht durch Null dividieren")
    return a / b
 
try:
    result = divide_numbers(10, 0)
    print(f"Ergebnis: {result}")
except ValueError as e:
    print(f"Fehler: {e}")

In diesem Beispiel überprüft die Funktion divide_numbers, ob das zweite Argument gleich 0 ist, und löst eine ValueError-Ausnahme aus, wenn dies der Fall ist. Anschließend rufen wir die Funktion divide_numbers in einem try-Block auf und behandeln die ValueError-Ausnahme im except-Block.

Fazit

In diesem Tutorial haben wir eine Vielzahl von Python-Themen behandelt, einschließlich Funktionen, Modulen und Paketen, Dateiein-/Ausgabe und Ausnahmebehandlung. Wir haben spezifische Beispiele und Code-Snippets bereitgestellt, um Ihnen diese Konzepte zu veranschaulichen und in Ihren eigenen Python-Projekten anzuwenden.

Python ist eine leistungsstarke und vielseitige Programmiersprache, die für eine Vielzahl von Aufgaben eingesetzt werden kann, von Webentwicklung über Datenanalyse bis hin zu maschinellem Lernen. Indem Sie die in diesem Tutorial behandelten Konzepte meistern, werden Sie auf dem besten Weg sein, ein versierter Python-Programmierer zu werden.

Denken Sie daran, dass das Erlernen einer Programmiersprache ein fortlaufender Prozess ist und der beste Weg, sich zu verbessern, darin besteht, zu üben, zu experimentieren und weiter zu lernen. Viel Glück!

MoeNagy Dev