5.2 Funktionales Training#

Aufgabe 1#

  • Schreibe eine Funktion, welche aus einem eingegebenen Preis und der eingegebenen Höhe des bezahlten Geldes das entsprechende Rückgeld berechnet und als Output ausgibt.

Aufgabe 2#

  • Schreibe eine Funktion, die die Länge einer Liste misst und zurückgibt, ohne dabei selbst die Funktion len() zu benutzen.

Aufgabe 3#

Funktionen erlauben uns im Kontext von ABM, den Code für ein Modell kompakt in einer Funktion zu speichern und gleichzeitig bestimmte Parameter des Modells über den Funktionsinput kontrollieren zu können. Das ist praktisch, wenn wir Simulationsexperimente durchführen, bei welchen wir das gleiche Modell mehrmals mit unterschiedlichen Parametern ausführen wollen, um den Effekt der Parameterveränderung zu untersuchen.

  • Nimm den untigen Code für das Nagel-Schreckenberg-Modell und verändere diesen so, dass er durch eine Funktion aufgerufen werden kann.

  • Definiere die Funktion so, dass Modellparameter deiner Wahl (z.B. die anfängliche Distanz zwischen den Agenten oder die Trödelwahrscheinlichkeit) mittels Funktionsinput kontrolliert werden können. Setze dabei Standardwerte für die Funktionsinputs, wenn du magst.

  • Rufe die definierte Funktion mit verschiedenen Inputwerten auf.

Aufgabe 4#

  • Verändere den Code so, dass du per Funktionsinput kontrollieren kannst, ob die grafische Darstellung der Simulation in der Konsole angezeigt wird oder nicht. Der Rest der Simulation sollte dennoch weiter funktionsfähig bleiben und bei Funktionsaufruf durchgeführt werden. Allein auf die grafische Darstellung sollte optional verzichtet werden können.

Code für NaSch-Modell#

### Schritt 1: Import von zusätzlichen Modulen ###
import random 


### Schritt 2: Definition wichtiger Parameter der Simulation ###

TICKS = 500 
MAX_SPEED = 5 
DAWDLING_PROB = 0.1 
N_AGENTS = 15
INITIAL_DISTANCE = 6
STREET_LEN = N_AGENTS * INITIAL_DISTANCE


### Schritt 3: Das Erstellen der Population ###

# Leere Liste, die gleich mit Agenten befüllt wird
population = []

# für jeden zu erstellenden Agenten
for i in range(N_AGENTS):
    
    # Agent als Dictionary erstellen
    agent = {
        "id": i,
        "position": i * INITIAL_DISTANCE,
        "speed": MAX_SPEED,
        "space_ahead": INITIAL_DISTANCE - 1,
    }
    
    # Agent an die Populationsliste hängen
    population.append(agent)

    
# Population nochmal überarbeiten - jeweils vorausfahrende und nachfahrende Agenten einspeichern
# für jeden Agenten in Population
for agent in population:
    # den vorausfahrenden Agenten merken/als Eigenschaft einspeichern
    agent.update({"agent_ahead": population[(agent["id"]+1)%len(population)]})
    
    # den nachfahrenden Agenten merken/als Eigenschaft einspeichern
    agent.update({"agent_behind": population[(agent["id"]-1)%len(population)]})
                 

        
### Schritt 4: Das Starten der Simulation mittels For-Loop durch die Zeit ###

# für jeden Zeitschritt
for tick in range(TICKS):
    
    ### Schritt 5: Die grafische Darstellung der Simulation ###
    
    # "leere" Straße als Liste von Punkten erstellen
    street_as_list = []
    for i in range(STREET_LEN):
        street_as_list.append(".")
        
    # für jeden Agenten
    for agent in population:
        # Agenten auf entsprechender Position auf Straße einfügen
        # Agent wird in diesem Fall als dessen Geschwindigkeit repräsentiert
        street_as_list[agent["position"]] = str(agent["speed"])
    
    # Repräsentation der Straße in einen String umwandeln
    street_as_string = "".join(street_as_list)
    
    # grafische Darstellung in Konsole anzeigen
    print(street_as_string)
    
    
    ### Schritt 6: das Handeln der Agenten ###
    
    # für jeden Agenten (die vier Handlungsschritte umsetzen)
    for agent in population:
        # 1. Acceleration
        if agent["speed"] < MAX_SPEED:
            agent["speed"] += 1
        
        # 2. Slowing down
        if agent["speed"] > agent["space_ahead"]:
            agent["speed"] = agent["space_ahead"]
        
        # 3. Randomization
        if agent["speed"] > 0 and random.random() <= DAWDLING_PROB:
            agent["speed"] -= 1
            
        # 4. Car motion
        agent["position"] = (agent["position"] + agent["speed"]) % STREET_LEN
    
    
    
    # für jeden Agenten (die Anzahl der freien Straßenabschnitte neu berechnen)
    for agent in population:
        # neue Anzahl der freien Zellen vor Agent berechnen und einspeichern
        agent["space_ahead"] -= agent["speed"]
        # neue Anzahl der freien Zellen vor dem NACHFAHRENDEM Agent berechnen und DIESEM einspeichern
        agent["agent_behind"]["space_ahead"] += agent["speed"]