Tracks
/
Python
Python
/
Übungen
/
Guidos wunderschöne Lasagne
Guidos wunderschöne Lasagne

Guidos wunderschöne Lasagne

Lernübung

Einführung

Python ist eine dynamisch und stark typisierte Programmiersprache. Sie nutzt sowohl Duck-Typing als auch graduelle Typisierung über Typ-Hinweise.

Python unterstützt zwar viele verschiedene Programmier-Stile, aber intern ist in Python alles ein Objekt. Das gilt für Zahlen, Strings, Listen und sogar Funktionen.

Was das alles bedeutet, schauen wir uns genauer an, wenn wir den Track weiter durchgehen.

Diese erste Übung stellt 4 wichtige Sprachmerkmale von Python vor:

  1. Zuweisung von Namen (Variablen und Konstanten),
  2. Funktionen (das Schlüsselwort def und das Schlüsselwort return),
  3. Kommentare, und
  4. Docstrings.

Note

Im Allgemeinen folgen Inhalte, Tests und Analyzer-Tools für den Python-Track den Stilkonventionen aus PEP 8 und PEP 257 für den Python-Codestil, mit der zusätzlichen (dringenden) Empfehlung, dass es keine einbuchstabigen Variablennamen und keine Variablen mit dem Namen "_" geben sollte.

Im Python-Track werden Variablen immer in snake_case geschrieben und Konstanten in SCREAMING_SNAKE_CASE.


Zuweisung von Namen (Variablen & Konstanten)

Programmierer können mit dem Zuweisungsoperator = Namen (auch Variablen genannt) an jeden Objekttyp binden: <name> = <value>. Ein Name kann während seiner Lebensdauer neu zugewiesen (oder neu gebunden) werden, an verschiedene Werte (verschiedene Objekttypen).

>>> my_first_variable = 1  #<-- my_first_variable bound to an integer object of value one.
>>> my_first_variable = 2  #<-- my_first_variable re-assigned to integer value 2.

>>> print(type(my_first_variable))
<class 'int'>

>>> print(my_first_variable)
2

>>> my_first_variable = "Now, I'm a string." #<-- You may re-bind a name to a different object type and value.
>>> print(type(my_first_variable))
<class 'str'>

>>> my_first_variable = 'You can call me "str".' #<-- Strings can be declared using single or double quote marks.
>>> print(my_first_variable)
You can call me "str".

Konstanten

Konstanten sind Namen, die in einem Programm nur einmal zugewiesen werden sollen. Sie sollten auf der Ebene eines Moduls (einer Datei) definiert werden und sind normalerweise für alle Funktionen und Klassen im Programm sichtbar. SCREAMING_SNAKE_CASE signalisiert, dass der Name nicht neu zugewiesen oder sein Wert nicht verändert werden sollte.

Funktionen

Das Schlüsselwort def leitet eine Funktionsdefinition ein. Jede Funktion kann in runden Klammern () null oder mehr formale Parameter haben, gefolgt von einem Doppelpunkt :. Die Anweisungen für den Körper der Funktion beginnen in der Zeile nach def und müssen in einem Block eingerückt sein.

# The body of a function is indented by 2 spaces, & prints the sum of the numbers.
def add_two_numbers(number_one, number_two):
  total = number_one + number_two
  print(total)  

>>> add_two_numbers(3, 4)
7


# Inconsistent indentation in your code blocks will raise an error.
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
...     result = number_one + number_two + number_three   # This was indented by 4 spaces.
...    print(result)     #this was only indented by 3 spaces
...
...
  File "<stdin>", line 3
    print(result)
    ^
IndentationError: unindent does not match any outer indentation level

Funktionen geben über das Schlüsselwort return explizit einen Wert oder ein Objekt zurück:

# Function definition on first line, explicit return used on final line.
>>> def add_two_numbers(number_one, number_two):
        return number_one + number_two   


# Calling the function in the Python shell returns the sum of the numbers.
>>> add_two_numbers(3, 4)
7

# Assigning the function call to a variable and printing it 
# will also return the value.
>>> sum_with_return = add_two_numbers(5, 6)
>>> print(sum_with_return)
11

Funktionen, auf deren return kein expliziter Ausdruck folgt, geben implizit das Objekt None zurück. Die Details von None werden in einer späteren Übung behandelt. Für diese Übung und Erklärung ist None ein Platzhalter, der nichts oder null repräsentiert:


# This function will return `None`
def square_a_number(number):
    square = number * number
    return # <-- note that this return is not followed by an expression

# Calling the function in the Python shell appears 
# to not return anything at all.
>>> square_a_number(2)
>>>


# Using print() with the function call shows that 
# the function is actually returning the **None** object.
>>> print(square_a_number(2))
None

Funktionen, die return weglassen, geben ebenfalls implizit das Objekt None zurück. Das heißt, wenn du return nicht in einer Funktion verwendest, gibt Python das Objekt None für dich zurück.

# This function omits a return keyword altogether.
def add_two_numbers(number_one, number_two):
  result = number_one + number_two

>>> add_two_numbers(5, 7)
>>> print(add_two_numbers(5, 7))
None

# Assigning the function call to a variable and printing 
# the variable will also show None.
>>> sum_without_return = add_two_numbers(5, 6)
>>> print(sum_without_return)
None

Funktionen aufrufen

Funktionen werden aufgerufen, indem man ihren Namen gefolgt von () verwendet. Die Punktnotation (.) wird verwendet, um Funktionen aufzurufen, die in einer Klasse oder einem Modul definiert sind.

>>> def raise_to_power(number, power):
...     return number ** power
...

>>> raise_to_power(3,3) # <--Invoking the function with the arguments 3 and 3.
27


# A mismatch between the number of parameters and the number of arguments will raise an error.
>>> raise_to_power(4,)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: raise_to_power() missing 1 required positional argument: 'power'


# Calling methods or functions in classes and modules.
>>> start_text = "my silly sentence for examples."
>>> str.upper(start_text)  # <--Calling the upper() method from the built-in str class on start_text.
'MY SILLY SENTENCE FOR EXAMPLES.'


# Importing the math module
>>> import math

>>> math.pow(2,4)  # <--Calling the pow() function from the math module.
16.0

Kommentare

Kommentare in Python beginnen mit einem #, das nicht Teil eines Strings ist, und enden am Zeilenende. Anders als viele andere Programmiersprachen unterstützt Python keine mehrzeiligen Kommentarzeichen. Jede Zeile eines Kommentarblocks muss mit dem Zeichen # beginnen.

Docstrings

Die erste Anweisung eines Funktionskörpers kann optional ein Docstring sein, der den Zweck der Funktion oder des Objekts kurz zusammenfasst. Docstrings werden mit dreifachen doppelten Anführungszeichen (""") deklariert, eingerückt auf derselben Ebene wie der Codeblock:


# An example from PEP257 of a multi-line docstring
# reformatted to use Google style non-type hinted docstrings.
# Some additional details can be found in the Sphinx documentation:
# https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#getting-started

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword Arguments:
        real (float): The real part of the number (default 0.0)
        imag (float): The imaginary part of the number (default 0.0)
        
    """

    if imag == 0.0 and real == 0.0:
        return complex_zero

Docstrings werden von automatisierten Dokumentationswerkzeugen wie Sphinx gelesen und durch Aufrufen des speziellen Attributs .__doc__ auf dem Funktions-, Methoden- oder Klassennamen zurückgegeben. Allgemeine Docstring-Konventionen sind in PEP257 beschrieben, aber das genaue Format variiert je nach Projekt und Team. Die Konzeptübungen von Exercism versuchen, dem Google-Stil für Code ohne Typ-Hinweise zu folgen.

Docstrings können auch als leichtgewichtige Unit-Tests dienen, die in einer späteren Übung behandelt werden.

# An example on a user-defined function using a Google style docstring. 
>>> def raise_to_power(number, power):
    """Raise a number to an arbitrary power.

    Parameters:
        number (int): The base number.
        power (int): The power to raise the base number to.
    
    Returns:
        int: The number raised to the specified power.
    
    Takes a number and raises it to the specified power, returning the result.

    """

    return number ** power
...

# Calling the .__doc__ attribute of the function and printing the result.
>>> print(raise_to_power.__doc__)
Raise a number to an arbitrary power.

Parameters:
    number (int): The base number.
    power (int): The power to raise the base number to.

Returns:
    int: The number raised to the specified power.

Takes a number and raises it to the specified power, returning the result.

Anleitung

Du schreibst etwas Code, mit dem du eine wunderbare Lasagne aus deinem Lieblingskochbuch kochen kannst.

Du hast fünf Aufgaben, die alle mit dem Kochen deines Rezepts zu tun haben.


Note

Die erste Funktionsdefinition haben wir in der Stub-Datei schon für dich begonnen, die übrigen Funktionsdefinitionen musst du aber selbst schreiben. Auch alle Konstanten musst du selbst definieren. Lies die #TODO-Kommentarzeilen in der Stub-Datei aufmerksam durch. Wenn du eine Aufgabe erledigt hast, entferne den TODO-Kommentar.


1. Definiere die erwartete Backzeit in Minuten als Konstante

Definiere die Konstante EXPECTED_BAKE_TIME, die angibt, wie viele Minuten die Lasagne im Ofen backen soll. Laut deinem Kochbuch sollte die Lasagne 40 Minuten im Ofen bleiben:

>>> print(EXPECTED_BAKE_TIME)
40

2. Berechne die verbleibende Backzeit in Minuten

Vervollständige die Funktion bake_time_remaining(), die die tatsächlichen Minuten, die die Lasagne schon im Ofen war, als Argument entgegennimmt und anhand der Konstante EXPECTED_BAKE_TIME zurückgibt, wie viele Minuten die Lasagne noch backen muss.

>>> bake_time_remaining(30)
10

3. Berechne die Vorbereitungszeit in Minuten

Definiere die Funktion preparation_time_in_minutes(), die die number_of_layers, die du zur Lasagne hinzufügen willst, als Argument entgegennimmt und zurückgibt, wie viele Minuten du für deren Zubereitung brauchst. Geh davon aus, dass jede Schicht 2 Minuten zum Vorbereiten braucht.

>>> def preparation_time_in_minutes(number_of_layers):
        ...
        ...
        
>>> preparation_time_in_minutes(2)
4

4. Berechne die insgesamt verstrichene Zeit (Vorbereitung + Backen) in Minuten

Definiere die Funktion elapsed_time_in_minutes(), die zwei Parameter als Argumente entgegennimmt:

  • number_of_layers (die Anzahl der Schichten, die zur Lasagne hinzugefügt wurden)
  • elapsed_bake_time (die Anzahl der Minuten, die die Lasagne schon im Ofen gebacken hat).

Diese Funktion soll die Gesamtzeit in Minuten zurückgeben, die du in der Küche mit Kochen verbracht hast: deine Vorbereitungszeit für die Schichten plus die Zeit, die die Lasagne im Ofen gebacken hat.

>>> def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
        ...
        ...
        
>>> elapsed_time_in_minutes(3, 20)
26

5. Aktualisiere das Rezept mit Notizen

Geh das Rezept noch einmal durch und ergänze „Notizen“ in Form von Funktions-Docstrings.

def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
    """Calculate the elapsed cooking time.
    
    Parameters:
        number_of_layers (int): The number of layers in the lasagna.
        elapsed_bake_time (int): Time the lasagna has been baking in the oven.
    
    Returns:
        int: The total time elapsed (in minutes) preparing and baking.

    This function takes two integers representing the number of lasagna 
    layers and the time already spent baking the lasagna. It calculates 
    the total elapsed minutes spent cooking (preparing + baking).
    
    """
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Python Exercism

Bereit, mit Guidos wunderschöne Lasagne zu starten?

Melde dich bei Exercism an, um Python mit 17 Konzepte146 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.