Python Crash Course

Kapitel 8

Funktionen

Wiederverwendbare Codeblöcke und Modularität

Was sind Funktionen?

  • Benannte Codeblöcke für bestimmte Aufgaben
  • Wiederverwendbar und modular
  • Können Parameter entgegennehmen
  • Können Werte zurückgeben
def greet_user():
    """Display a simple greeting."""
    print("Hello!")

greet_user()  # Funktion aufrufen

def greet_user(username):
    """Display a personalized greeting."""
    print(f"Hello, {username.title()}!")

greet_user('jesse')

Parameter und Argumente

# Positionsabhängige Argumente
def describe_pet(animal_type, pet_name):
    """Display information about a pet."""
    print(f"\nI have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name.title()}.")

describe_pet('hamster', 'harry')
describe_pet('dog', 'willie')

# Schlüsselwort-Argumente
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='willie', animal_type='dog')

🛠️ Übung 1: Einfache Funktionen

🔗 jupyter.gymnasium-hummelsbuettel.de

Aufgaben 8-1 und 8-2:

  • 8-1: Nachricht - display_message()
  • 8-2: Lieblingsbuch - favorite_book()

→ kapitel_8_aufgaben_8-1_8-2.ipynb

↓ Lösungen

💡 Lösung 8-1

# 8-1: Nachricht
def display_message():
    """Display a message about what I'm learning in this chapter."""
    print("I'm learning about functions in this chapter.")
    print("Functions help organize code and make it reusable.")

display_message()

📄 Ausgabe 8-1

I'm learning about functions in this chapter.
Functions help organize code and make it reusable.

💡 Lösung 8-2

# 8-2: Lieblingsbuch
def favorite_book(title):
    """Display a message about my favorite book."""
    print(f"One of my favorite books is {title}.")

favorite_book("Alice in Wonderland")
favorite_book("The Hitchhiker's Guide to the Galaxy")

📄 Ausgabe 8-2

One of my favorite books is Alice in Wonderland.
One of my favorite books is The Hitchhiker's Guide to the Galaxy.

Standardwerte für Parameter

def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print(f"\nI have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name.title()}.")

# Standard verwenden
describe_pet(pet_name='willie')

# Standard überschreiben
describe_pet(pet_name='harry', animal_type='hamster')

# Positionsabhängig
describe_pet('willie')
describe_pet('harry', 'hamster')

🛠️ Übung 2: Parameter und Standardwerte

Aufgaben 8-3 bis 8-5:

  • 8-3: T-Shirt - Größe und Text
  • 8-4: Große T-Shirts - Standardwerte
  • 8-5: Städte - Stadt und Land

→ kapitel_8_aufgaben_8-3_8-5.ipynb

↓ Lösungen

💡 Lösung 8-3

# 8-3: T-Shirt
def make_shirt(size, message):
    """Make a shirt with given size and message."""
    print(f"Making a {size} shirt with the message: '{message}'")

make_shirt('L', 'Python is awesome!')
make_shirt(size='M', message='I love coding')

📄 Ausgabe 8-3

Making a L shirt with the message: 'Python is awesome!'
Making a M shirt with the message: 'I love coding'

💡 Lösung 8-4

# 8-4: Große T-Shirts
def make_shirt(size='L', message='I love Python'):
    """Make a shirt with given size and message."""
    print(f"Making a {size} shirt with the message: '{message}'")

make_shirt()  # L, Standard-Text
make_shirt(size='M')  # M, Standard-Text
make_shirt('S', 'Custom message!')  # S, eigener Text

📄 Ausgabe 8-4

Making a L shirt with the message: 'I love Python'
Making a M shirt with the message: 'I love Python'
Making a S shirt with the message: 'Custom message!'

💡 Lösung 8-5

# 8-5: Städte
def describe_city(city, country='Deutschland'):
    """Describe a city and its country."""
    print(f"{city} is in {country}.")

describe_city('Hamburg')
describe_city('Berlin')
describe_city('Reykjavik', 'Iceland')

📄 Ausgabe 8-5

Hamburg is in Deutschland.
Berlin is in Deutschland.
Reykjavik is in Iceland.

Rückgabewerte

def get_formatted_name(first_name, last_name):
    """Return a full name, neatly formatted."""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
print(musician)

# Optionale Parameter
def get_formatted_name(first_name, last_name, middle_name=''):
    """Return a full name, neatly formatted."""
    if middle_name:
        full_name = f"{first_name} {middle_name} {last_name}"
    else:
        full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
musician = get_formatted_name('john', 'hooker', 'lee')

Dictionaries zurückgeben

def build_person(first_name, last_name, age=None):
    """Return a dictionary of information about a person."""
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person

musician = build_person('jimi', 'hendrix', age=27)
print(musician)
# {'first': 'jimi', 'last': 'hendrix', 'age': 27}

# Funktion mit while-Schleife
def get_formatted_name(first_name, last_name):
    """Return a full name, neatly formatted."""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

while True:
    print("\nPlease tell me your name:")
    print("(enter 'q' at any time to quit)")
    
    f_name = input("First name: ")
    if f_name == 'q':
        break
    
    l_name = input("Last name: ")
    if l_name == 'q':
        break
    
    formatted_name = get_formatted_name(f_name, l_name)
    print(f"\nHello, {formatted_name}!")

🛠️ Übung 3: Rückgabewerte

Aufgaben 8-6 bis 8-8:

  • 8-6: Städtenamen - String zurückgeben
  • 8-7: Album - Dictionary erstellen
  • 8-8: Album aus Benutzereingaben

→ kapitel_8_aufgaben_8-6_8-8.ipynb

↓ Lösungen

💡 Lösung 8-6

# 8-6: Städtenamen
def city_country(city, country):
    """Return a string like 'Santiago, Chile'."""
    return f"{city}, {country}"

result1 = city_country('Santiago', 'Chile')
result2 = city_country('Hamburg', 'Deutschland')
result3 = city_country('Tokyo', 'Japan')

print(result1)
print(result2)
print(result3)

📄 Ausgabe 8-6

Santiago, Chile
Hamburg, Deutschland
Tokyo, Japan

💡 Lösung 8-7

# 8-7: Album
def make_album(artist, title, tracks=None):
    """Build a dictionary describing a music album."""
    album = {'artist': artist, 'title': title}
    if tracks:
        album['tracks'] = tracks
    return album

album1 = make_album('Pink Floyd', 'The Dark Side of the Moon')
album2 = make_album('Led Zeppelin', 'IV')
album3 = make_album('The Beatles', 'Abbey Road', tracks=17)

print(album1)
print(album2)
print(album3)

📄 Ausgabe 8-7

{'artist': 'Pink Floyd', 'title': 'The Dark Side of the Moon'}
{'artist': 'Led Zeppelin', 'title': 'IV'}
{'artist': 'The Beatles', 'title': 'Abbey Road', 'tracks': 17}

💡 Lösung 8-8

# 8-8: Album aus Benutzereingaben
def make_album(artist, title, tracks=None):
    """Build a dictionary describing a music album."""
    album = {'artist': artist, 'title': title}
    if tracks:
        album['tracks'] = tracks
    return album

while True:
    print("\nEnter album information:")
    print("(enter 'quit' at any time to exit)")
    
    artist = input("Artist name: ")
    if artist == 'quit':
        break
    
    title = input("Album title: ")
    if title == 'quit':
        break
    
    album = make_album(artist, title)
    print(album)

📄 Ausgabe 8-8

Enter album information:
(enter 'quit' at any time to exit)
Artist name: Queen
Album title: Bohemian Rhapsody
{'artist': 'Queen', 'title': 'Bohemian Rhapsody'}

Enter album information:
(enter 'quit' at any time to exit)
Artist name: quit

Listen an Funktionen übergeben

def greet_users(names):
    """Print a simple greeting to each user in the list."""
    for name in names:
        msg = f"Hello, {name.title()}!"
        print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

# Listen in Funktionen ändern
def print_models(unprinted_designs, completed_models):
    """Simulate printing each design, until none are left."""
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print(f"Printing model: {current_design}")
        completed_models.append(current_design)

def show_completed_models(completed_models):
    """Show all the models that were printed."""
    print("\nThe following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)

🛠️ Übung 4: Listen und Funktionen

Aufgaben 8-9 bis 8-11:

  • 8-9: Nachrichten - Liste ausgeben
  • 8-10: Nachrichten senden - Listen verschieben
  • 8-11: Archivierte Nachrichten - Kopie verwenden

→ kapitel_8_aufgaben_8-9_8-11.ipynb

↓ Lösungen

💡 Lösung 8-9

# 8-9: Nachrichten
def show_messages(messages):
    """Print all messages in the list."""
    for message in messages:
        print(message)

text_messages = ["Hello!", "How are you?", "See you later!"]
show_messages(text_messages)

📄 Ausgabe 8-9

Hello!
How are you?
See you later!

💡 Lösung 8-10

# 8-10: Nachrichten senden
def send_messages(messages, sent_messages):
    """Print each message and move it to sent_messages."""
    while messages:
        current_message = messages.pop()
        print(current_message)
        sent_messages.append(current_message)

messages = ["Hello!", "How are you?", "See you later!"]
sent_messages = []

send_messages(messages, sent_messages)
print(f"Original messages: {messages}")
print(f"Sent messages: {sent_messages}")

📄 Ausgabe 8-10

See you later!
How are you?
Hello!
Original messages: []
Sent messages: ['See you later!', 'How are you?', 'Hello!']

💡 Lösung 8-11

# 8-11: Archivierte Nachrichten
def send_messages(messages, sent_messages):
    """Print each message and move it to sent_messages."""
    while messages:
        current_message = messages.pop()
        print(current_message)
        sent_messages.append(current_message)

messages = ["Hello!", "How are you?", "See you later!"]
sent_messages = []

send_messages(messages[:], sent_messages)  # Kopie übergeben
print(f"Original messages: {messages}")
print(f"Sent messages: {sent_messages}")

📄 Ausgabe 8-11

See you later!
How are you?
Hello!
Original messages: ['Hello!', 'How are you?', 'See you later!']
Sent messages: ['See you later!', 'How are you?', 'Hello!']

*args - Beliebige Anzahl Argumente

# *args für beliebig viele Positionsargumente
def make_pizza(*toppings):
    """Print the list of toppings that have been requested."""
    print(toppings)

make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

Normale + *args Argumente mischen

# Feste Parameter + beliebige Parameter
def make_pizza(size, *toppings):
    """Summarize the pizza we are about to make."""
    print(f"\nMaking a {size}-inch pizza with the following toppings:")
    for topping in toppings:
        print(f"- {topping}")

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

Beliebige Schlüsselwort-Argumente

def build_profile(first, last, **user_info):
    """Build a dictionary containing everything we know about a user."""
    user_info['first_name'] = first
    user_info['last_name'] = last
    return user_info

user_profile = build_profile('albert', 'einstein',
                           location='princeton',
                           field='physics')
print(user_profile)

# Ausgabe:
# {'location': 'princeton', 'field': 'physics', 
#  'first_name': 'albert', 'last_name': 'einstein'}

🛠️ Übung 5: Flexible Argumente

Aufgaben 8-12 bis 8-14:

  • 8-12: Sandwiches - *args verwenden
  • 8-13: Benutzerprofil - **kwargs
  • 8-14: Autos - flexibles Dictionary

→ kapitel_8_aufgaben_8-12_8-14.ipynb

↓ Lösungen

💡 Lösung 8-12

# 8-12: Sandwiches
def make_sandwich(*ingredients):
    """Make a sandwich with given ingredients."""
    print("Making a sandwich with the following ingredients:")
    for ingredient in ingredients:
        print(f"- {ingredient}")
    print()

make_sandwich('ham')
make_sandwich('turkey', 'cheese')
make_sandwich('tuna', 'lettuce', 'tomato', 'mayonnaise')

📄 Ausgabe 8-12

Making a sandwich with the following ingredients:
- ham

Making a sandwich with the following ingredients:
- turkey
- cheese

Making a sandwich with the following ingredients:
- tuna
- lettuce
- tomato
- mayonnaise

💡 Lösung 8-13

# 8-13: Benutzerprofil
def build_profile(first, last, **user_info):
    """Build a dictionary containing everything about a user."""
    user_info['first_name'] = first
    user_info['last_name'] = last
    return user_info

my_profile = build_profile('Max', 'Mustermann',
                          location='Hamburg',
                          field='Computer Science',
                          age=25)
print(my_profile)

📄 Ausgabe 8-13

{'location': 'Hamburg', 'field': 'Computer Science', 'age': 25, 'first_name': 'Max', 'last_name': 'Mustermann'}

💡 Lösung 8-14

# 8-14: Autos
def make_car(manufacturer, model, **car_info):
    """Build a dictionary containing car information."""
    car_info['manufacturer'] = manufacturer
    car_info['model'] = model
    return car_info

car = make_car('subaru', 'outback', color='blue', tow_package=True)
print(car)

📄 Ausgabe 8-14

{'color': 'blue', 'tow_package': True, 'manufacturer': 'subaru', 'model': 'outback'}

Funktionen in Modulen speichern

# pizza.py
def make_pizza(size, *toppings):
    """Summarize the pizza we are about to make."""
    print(f"\nMaking a {size}-inch pizza with the following toppings:")
    for topping in toppings:
        print(f"- {topping}")

# making_pizzas.py
import pizza

pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

# Alternativen:
from pizza import make_pizza
from pizza import make_pizza as mp
import pizza as p
from pizza import *

🛠️ Übung 6: Module

Aufgaben 8-15 bis 8-17:

  • 8-15: 3D-Druck - Funktionen in Modul
  • 8-16: Import - verschiedene Importarten
  • 8-17: Gestaltung von Funktionen

→ kapitel_8_aufgaben_8-15_8-17.ipynb

↓ Lösungen

💡 Lösung 8-15 (Teil 1)

# 8-15: 3D-Druck - printing_functions.py Modul
def print_models(unprinted_designs, completed_models):
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print(f"Printing model: {current_design}")
        completed_models.append(current_design)

def show_completed_models(completed_models):
    print("\nThe following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)

💡 Lösung 8-15 (Teil 2)

# printing_models.py - Hauptprogramm
import printing_functions as pf

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []

pf.print_models(unprinted_designs, completed_models)
pf.show_completed_models(completed_models)

📄 Ausgabe 8-15

Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

💡 Lösung 8-16 (Teil 1)

# 8-16: Import-Varianten
# Verschiedene Arten, Module zu importieren:

# 1. Ganzes Modul importieren
import printing_functions

# 2. Spezifische Funktion importieren
from printing_functions import print_models

# 3. Funktion mit Alias importieren
from printing_functions import print_models as pm

💡 Lösung 8-16 (Teil 2)

# 4. Modul mit Alias importieren
import printing_functions as pf

# 5. Alle Funktionen importieren (nicht empfohlen)
from printing_functions import *

📄 Ausgabe 8-16

# Keine Ausgabe - dies zeigt nur Import-Syntax

💡 Lösung 8-17

# 8-17: Gestaltung von Funktionen
# Richtlinien für gute Funktionen:

def calculate_area(length, width):
    """
    Berechne die Fläche eines Rechtecks.
    
    Gute Praktiken:
    - Aussagekräftiger Name
    - Klare Parameter
    - Dokumentation (docstring)
    - Eine spezifische Aufgabe
    - Rückgabewert wenn sinnvoll
    """
    area = length * width
    return area

# Verwendung:
result = calculate_area(5, 3)
print(f"Die Fläche beträgt: {result} Quadrateinheiten")

📄 Ausgabe 8-17

Die Fläche beträgt: 15 Quadrateinheiten

Zusammenfassung Kapitel 8

  • Funktionen: Wiederverwendbare Codeblöcke
  • Parameter: Daten an Funktionen übergeben
  • Standardwerte: Optionale Parameter
  • Rückgabewerte: Ergebnisse zurückgeben
  • *args/**kwargs: Flexible Argumentanzahl
  • Module: Funktionen organisieren und teilen

Praktische Tipps

  • Funktionsnamen: Beschreibend und mit Verben
  • Docstrings: Immer Funktionen dokumentieren
  • Ein Zweck: Eine Funktion, eine Aufgabe
  • Parameter-Reihenfolge: Pflicht-, optionale, *args, **kwargs
# Gute Funktion
def calculate_area(length, width):
    """Calculate and return the area of a rectangle."""
    return length * width

# Gute Parameterreihenfolge
def example_function(required_param, optional_param='default', 
                    *args, **kwargs):
    pass