Grundlagen Python (4/5): Funktionen, Programmierstil

Bildschirm mit Code - Grundlagen Python
  • Funktionen (mit Parametern und Rückgabewerten)
  • Programmierstil (PEP, Zen of Python)

Dieser Blog erklärt die Grundlagen der Programmiersprache Python anhand eines Projektes – ein Programm, mit dem sich Kopfrechnen trainieren lässt. Am Ende dieser Revision kann das Programm beliebig viele Aufgaben stellen und abschließend eine Gesamtbewertung geben.

Kopfrechnen Version 0.4

Bisher haben wir den Code durch Kommentare unterteilt. Dadurch hat unser Programm eine gewisse Struktur, aber die Codeabschnitte sind beispielsweise nicht wiederverwendbar. Unser nächster Schritt wird sein, diese Codeabschnitte in Funktionen zu wandeln (beispielsweise Zufallszahlen, Addition, Hauptprogramm).
In dieser Version soll solange eine neue Aufgabe gestellt werden, bis statt das Ergebnis das Wort „ende“ eingegeben wird.
Ausserdem achten wir auf das Zen von Python (soweit möglich).

Grundlagen Python: Funktionen

Funktionen sind wesentlich, um Lesbarkeit des Codes zu erhöhen, Fehler zu minimieren und Wiederverwendbarkeit zu ermöglichen. Daher werden wesentliche Programmelemente als Funktion definiert.
Funktionen werden generell mit dem Schlüsselwort def definiert, gefolgt vom Funktionsnamen, runden Klammer (ggf. mit Parametern) und einem Doppelpunkt. Die auszuführenden Anweisungen werden eingerückt. Mit dem Schlüsselwort return können Werte zurückgegeben werden, beispielsweise um einer Variablen einen Wert zuzuweisen.
Um die Funktion auszuführen, muss sie dezidiert aufgerufen werden.

def funktion_ohne_alles():
  print("Hallo Welt")

funktion_ohne_alles()
Hallo Welt

Funktionen können (müssen aber nicht) Ergebnisse mit dem Befehl return zurückgeben. Diese zurückgegebenen Werte können (müssen aber nicht) verwendet werden.

def funktion_mit_rückgabe():
  print("Hallo in der Funktion")
  return "Hallo als Rückgabewert"

funktion_mit_rückgabe()

text=funktion_mit_rückgabe()
print (text)
Hallo in der Funktion
Hallo in der Funktion
Hallo als Rückgabewert

Funktionen können (müssen aber nicht) Argumente enthalten, die in der Klammer hinter ihrem Namen aufgelistet werden. Diese können auch vordefiniert sein und ein Parameter überschreibt dann den Standartwert.

def funktion_mit_parameter(variable="Hallo"):
  print(variable)

funktion_mit_parameter()
funktion_mit_parameter("Hallo Welt")
Hallo
Hallo Welt

Mit Funktionen kann man auch noch mehr machen, wie die Beispiele unten zeigen.

def funktion (zeichen="#", zahl1=5, zahl2=1):
  return zeichen*zahl1*zahl2

def funktion_komplex (zeichen="#", zahl1=5, zahl2=1):
  produkt = zahl1*zahl2
  return zeichen*produkt, produkt

variable=funktion("*")
print(variable)
variable=funktion("*", 10)
print(variable)
variable=funktion("*", 10, 2)
print(variable)
variable=funktion("*", zahl2=3, zahl1=3)
print(variable)

(text,zahl)=(funktion_komplex())
print(funktion_komplex())
print(text*zahl)
*****
**********
********************
*********
('#####', 5)
#########################

Grundlagen Python: Programmierstil (PEP, Zen of Python und anderes)

Wir können zu diesem frühen Zeitpunkt erkennen, dass die steigende Komplexität des Programms mehr Struktur erfordert. In der Literatur gibt es dazu verschiedene Ansätze, hier legen wir als interne Richtlinie folgende Punkte fest:

  • maximal 79 Zeichen pro Zeile (dadurch erhalten wir eine gute Lesbarkeit auf Papier oder Bildschirm – siehe auch vertikale Linie innerhalb der Codefenster),
  • maximal 30 Codezeilen pro Block (auch hier wäre weniger besser)
  • maximal 7 Arbeitsschritte pro Block
  • kommentierte Programmbereiche
    • #initialisierungen: Import von Bibliotheken und Definition von globalen Variablen
    • #aufgabe erstellen: Funktionen, die mit der Aufgabenstellung im Zusammenhang stehen
    • #eingabe bewerten: Funktionen, die die Eingabe und Bewertung durchführen
    • #hauptprogramm: die primäre Funktion und ihr Aufruf

Außerdem versuchen wir, möglichst wenige globale Variablen zu benutzen.


PEP 8

Python-spezifisch gibt es noch einige sogenennate PEPs. PEP 8 steht für „Python Enhancement Proposal 8“ und stellt den „Style Guide for Python Code“ dar. Einige der wichtigsten Punkte sind:

  1. Einrückung: Verwendung von 4 Leerzeichen pro Einrückungsebene (keine Tabulatoren).
  2. Zeilenlänge: Empfehlung, dass Zeilen 79 Zeichen nicht überschreiten sollten, um die Lesbarkeit zu fördern.
  3. Leerzeichen: Verwendung von Leerzeichen um Operatoren und nach Kommas, aber keine Leerzeichen am Ende von Zeilen oder vor Einzugsanfängen.
  4. Zeilen und Zeilenwechsel: Empfehlungen für die Verwendung von Leerzeilen zur logischen Trennung von Codeblöcken.
  5. Naming Conventions: Konventionen für die Benennung von Variablen, Funktionen, Klassen und Modulen, z. B. Verwendung von „snake_case“ für Funktionen und Variablen sowie „CamelCase“ für Klassennamen.
  6. Import-Anweisungen: Richtlinien für die Formatierung von Import-Anweisungen und die Reihenfolge der Imports.

Vieles davon haben wir schon verwendet bzw. umgesetzt, ohne es explizit zu erwähnen. Ein einheitlicher Stil erleichtert auch die Zusammenarbeit in Projekten und fördert die Lesbarkeit und Wartbarkeit des Codes.


PEP 20 – The Zen of Python

Daneben gibt es noch PEP 20, Zen von Python genannt. Die 19 teilweise humorvollen Regeln beinhalten verschiedene Bereiche, Programmieren im Allgemeinen zu verbessern. Man kann sie sich auch als sogenanntes Easter Egg mit import this anzeigen lassen.

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Auf Deutsch könnte man wie folgt übersetzen:

  • Elegant (bzw. schön) ist besser als hässlich.
  • Explizit ist besser als implizit.
  • Einfach ist besser als komplex.
  • Komplex ist aber immer noch besser als kompliziert.
  • Flach ist besser als verschachtelt.
  • Sparsam ist besser als dicht.
  • Lesbarkeit zählt.
  • Sonderfälle sind nicht besonders genug, um die Regeln zu brechen.
  • Wobei Praktikabilität Reinheit schlägt.
  • Fehler sollten niemals stillschweigend passieren.
  • Sofern sie nicht ausdrücklich zum Schweigen gebracht werden.
  • Widerstehe angesichts von Mehrdeutigkeiten der Versuchung zu raten.
  • Es sollte einen – und vorzugsweise nur einen – offensichtlichen Weg geben, dies zu tun.
  • Obwohl dies zunächst nicht offensichtlich ist, es sei denn, Sie sind Niederländer.
  • Jetzt ist besser als nie.
  • Obwohl nie oft besser ist als genau jetzt.
  • Wenn eine Implementierung schwer zu erklären ist, ist es eine schlechte Idee.
  • Wenn eine Implementierung einfach zu erklären ist, könnte es eine gute Idee sein.
  • Namensräume sind eine großartige Idee – machen wir mehr davon!

Damit können wir nun die vierte Version des Programms fertigstellen.

Programm

###
# Bibliotheken laden
###

import random

###
# Funktionen definieren
###

def willkommen_anzeigen():
    print("Willkommen beim Kopfrechnen.")
    print("Dir werden jetzt Rechenaufgaben gestellt.")
    print("Wenn Du aufhören möchtest, tippe das Wort 'ende' ein")

def aufgabe_stellen():
    a=random.randint(1, 5) # Zufallszahl erzeugen
    b=random.randint(1, 5) # Zufallszahl erzeugen
    print(f"Wieviel ist {a} + {b}?") # Aufgabe anzeigen
    return a+b # Ergebnis berechnen und zurückgeben

def antwort_eingeben():
    while True:
        eingabe = input("Dein Ergebnis = ")
        if eingabe.lower() == "ende":
            print("Spiel wird beendet\n")
            return -1
        try:
            eingabe = int(eingabe)
            break
        except ValueError:
            print("Bitte eine ganze Zahl oder 'ende' eingeben")
    return eingabe

def antwort_bewerten (ergebnis, antwort):
    if antwort==ergebnis:
        print("Richtig\n")
        return 1
    else:
        print(f"{antwort} ist falsch. Das richtige Ergebnis lautet {ergebnis}\n")
        return 0

def kopfrechnen():
    runden=0
    richtig=0
    willkommen_anzeigen
    while True:
          ergebnis=aufgabe_stellen()
          antwort=antwort_eingeben()
          if antwort<0:
              break
          else:
              richtig += antwort_bewerten (ergebnis, antwort)
          runden += 1
    print (f"Du hast insgesamt {richtig} von {runden} Aufgaben richtig")


###
# hauptprogramm
###

kopfrechnen()

Ein möglicher Ablauf könnte wie folgt aussehen

Wieviel ist 1 + 2?
Dein Ergebnis = 3
Richtig

Wieviel ist 1 + 2?
Dein Ergebnis = 3
Richtig

Wieviel ist 3 + 2?
Dein Ergebnis = 3
3 ist falsch. Das richtige Ergebnis lautet 5

Wieviel ist 2 + 4?
Dein Ergebnis = ende
Spiel wird beendet

Du hast insgesamt 2 von 3 Aufgaben richtig

Die kompletten Grundlagen Python

Kopfrechnen Version 0.1

Additionsaufgabe mit zwei Zahlen stellen

  • Variablen
  • Ausgabe mit print()
  • Eingabe mit input()

Link: https://kiwi-strategie.de/grundlagen-python-1-5/

Kopfrechnen Version 0.2

Additionsaufgabe mit zwei Zufallszahlen stellen und das Ergebnis bewerten

  • Kommentare
  • Bibliotheken einbinden (am Beispiel von random)
  • Verzweigungen mit ifelse und elif

Link: https://kiwi-strategie.de/grundlagen-python-2-5/

Kopfrechnen Version 0.3

Mehrere Additionsaufgaben stellen und falsche Eingabeformate zurückweisen

  • Schleifen mit for und while
  • Fehlerbehandlung

Link: https://kiwi-strategie.de/grundlagen-python-3-5/

Kopfrechnen Version 0.4

Beliebig viele Aufgaben stellen mit abschließender Gesamtbewertung

  • Funktionen (mit Parametern und Rückgabewerten)
  • Programmierstil (PEP, Zen of Python)

Link: https://kiwi-strategie.de/grundlagen-python-4-5/

Kopfrechnen Version 1.0

Weitere Aufgabetypen abfragen sowie Spielstand laden und speichern

  • komplexere Datenstrukturen (Listen und Dictionaries)
  • externe Daten lesen und schreiben

Link: https://kiwi-strategie.de/grundlagen-python-5-5/

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert