Seite 1 von 1

Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 12:58
von Patsche
Hi!

Ich habe bisher immer mit globalen Variablen gearbeiten, was ja aber nicht gut ist. Das möchte ich jetzt ändern.
Jetzt habe ich aber ein Problem, wie ich Rückgabewerte von Funktionen.
Mir fällt es auch immer schwer beispiele aus dem Internet zu verstehen, weil ich nie so recht weiß, welches Wort nun eine Variable ist, die selbst ausgedacht ist, oder ob das Wort schon belegt ist, wie beispielsweise "print". Erschwerend kommt hinzu, dass vieles auf englisch geschrieben wird. Wäre es auf deutsch, dann könnte ich das ja rausfiltern, weil belegte "Wörter" halt auf englisch wären und der Rest auf deutsch.
Aber egal.
Hier habe ich mal ein kleines Beispiel geschrieben:

Code: Alles auswählen

def addieren(a,b):
    c=a+b
    return c
    
def subtrahieren(a,b):
    c=a-b
    return c

def multiplizieren(a,b):
    c=a*b
    return c

def dividieren(a,b):
    c=a/b
    return c

a=int(input("Bitte Zahl 1 eingeben: "))
b=int(input("Bitte Zahl 2 eingeben: "))
print("Was möchten Sie mit den Zahlen tun?")
print("    1.addieren")
print("    2.subtrahieren")
print("    3.multiplizieren")
print("    4.dividieren")

auswahl=int(input("Ihre Antwort:  "))

if auswahl==1:
    addieren(a,b)
    print("Ergebnis: ",c)

elif auswahl==2:
    subtrahieren(a,b)
    print("Ergebnis: ",c)

elif auswahl==3:
    multiplizieren(a,b)
    print("Ergebnis: ",c)

elif auswahl==4:
    dividieren(a,b)
    print("Ergebnis: ",c)
Das Programm möchte vom Benutzer 2 Zahlen haben und fragt dann, was mit diesen gemacht werden soll. Klar bräuchte man jetzt keine Funktionen, aber ich möchte ja genau das gerade lernen.
Ok also weiter:
Der Funktion werden die Zahlen in a und b übergeben und in der Definition der Funktion habe ich auch definiert, dass ihr a und b übergeben werden muss.
Das verstehe ich auch.
In der Funktionen werden a und b verarbeitet und in c gespeichert.
Die Funktion gibt das Ergebnis in c wieder durch das "return" zurück.
Jetzt soll c ausgegeben werden, aber ich bekomme halt den Fehler, dass c nicht definiert wurde.
Hier ist eben mein Problem.
Die Funktion soll c zurückgeben, aber das passiert ja nicht.
Kann mir da jemand helfen und den Code entsprechen hier posten?

Vielen Dank für eure Hilfe!

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 13:07
von rogerb
@Patsche,

"c" ist nur innerhalb der Funktionen definiert. Um den Wert von "c" ausserhalb der Funktion verwenden zu können, must du den Funktionsaufruf einer oder mehrerer Variablen zuweisen:

Code: Alles auswählen

if auswahl==1:
    ergebnis = addieren(a,b)
    print("Ergebnis: ", ergebnis)

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 13:08
von Sirius3
Die Funktion gibt einen Wert zurück, aber mit dem Wert machst Du nichts. Es ist das selbe, wie bei den Funktionen `input` und `int`, die Du ja korrekt benutzt:

Code: Alles auswählen

def subtrahieren(a, b):
    c = a - b
    return c

ergebnis = subtrahieren(17, 6)
print(ergebnis)
Prinzipiell kannst Du jeden Namen, der kein Schlüsselwort ist, benutzen, also auch `print = 17`. Probleme bekommst Du, wenn Du `print` zum Ausgeben benutzen willst.

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 13:23
von Patsche
rogerb hat geschrieben: Sonntag 24. Oktober 2021, 13:07 @Patsche,

"c" ist nur innerhalb der Funktionen definiert. Um den Wert von "c" ausserhalb der Funktion verwenden zu können, must du den Funktionsaufruf einer oder mehrerer Variablen zuweisen:

Code: Alles auswählen

if auswahl==1:
    ergebnis = addieren(a,b)
    print("Ergebnis: ", ergebnis)
Ja so klappt es, wenn ich a und b nehme.
Ich möchte ja aber nicht mit a und b weitermachen, sondern mit der Variable c.


So klappt es leider auch nicht:

Code: Alles auswählen

if auswahl==1:
    addieren(a,b)
    c=addieren(c)
    print(c)
So erstelle ich doch eine neue Variable c und weise ihr den Wert der Variable c aus der Funktion zu. Aber das klappt auch nicht.
Das muss doch irgendwie möglich sein. Oder macht man das eben auch nicht?
Sirius3 hat geschrieben: Sonntag 24. Oktober 2021, 13:08 Prinzipiell kannst Du jeden Namen, der kein Schlüsselwort ist, benutzen, also auch `print = 17`. Probleme bekommst Du, wenn Du `print` zum Ausgeben benutzen willst.
Ja eben. Wenn man aber nicht alle Schlüsselwörter kennt und dann Beispiele anguckt, wo die Wörter auf englisch und nicht farblich hervorgehoben werden, dann weißß ich nie, ob das jetzt ein Schlüsselwort ist oder eben nciht.......

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 13:32
von rogerb

Code: Alles auswählen

if auswahl==1:
    addieren(a,b)
    
    # Das "c" in der Klammer wird zuerst ausgewertet, ist zu dem Zeitpunkt aber noch unbekannt. Daher gibt es einen Fehler
    c=addieren(c)
    print(c)
Daher:

Code: Alles auswählen

if auswahl==1:
    c = addieren(a,b)
    print(c)

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:00
von Patsche
Und genau da liegt mein Denkproblem. Warum ist das (c) noch nicht verfügbar?
Ich ruf ja die Funktion auf und errechnen den Wert aus a und b und rechne das Funktions c aus gebe ihn als c zurück.
Also muss doch das "Funktions c" schon abgearbeitet worden sein.
Wieso ist es denn nicht verfügbar, wenn ich es in das "Haupt-C" schieben will?

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:15
von rogerb
Dann kommen wir der Sache schon näher. Du hast anscheinen angenommen, dass die Namen, die in der Funktion definiert werden auch außerhalb definiert sind. Das ist nicht der Fall.

Code: Alles auswählen

def function():
    a = 10

# Ergibt einen NameError
print(a)
Das ist auch gut so sonst, gäbe es ein riesiges Durcheinander. Über den Rückgabewert hat man die Kontrolle, was aus der Funktion wieder nach außen gelangt.
So funktioniert es. Auch wenn ich hier außerhalb und innerhalb der Funktion "a" verwende, gelangt der Wert von a innerhalb der Funktion nur über die Rückgabe an das "a" außerhalb der Funktion.

Code: Alles auswählen

def function():
    a = 10
    return a

a = function()
print(a)

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:15
von ThomasL
Du bist immer noch in diesen "globalen" Denkstrukturen gefangen und musst dich davon lösen.
Die Variable c ist jeweils nur innerhalb der Funktion definiert und nicht außerhalb.
Um den errechneten Wert außerhalb der Funktion weiterverwenden zu können gibt man ihn per return an den Aufruf zurück.

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:40
von Patsche
ThomasL hat geschrieben: Sonntag 24. Oktober 2021, 14:15 Die Variable c ist jeweils nur innerhalb der Funktion definiert und nicht außerhalb.
Und warum ist es das?
Wir bleiben jetzt beispielhaft hier:

Code: Alles auswählen

def addieren(a,b):
    c=a+b
    return c
Hier habe ich c innerhalb der Funktion definiert. Soweit richtig. Das vetsehe ich. Und auch das c nicht außerhalb verfügbar ist.
Und hier der Teil im Hauptprogramm:

Code: Alles auswählen

if auswahl==1:
    addieren(a,b)    <-----------------
    c=addieren(c)
    print(c)
Ich rufe die Funktion auf und erhalte das c zurück.

Code: Alles auswählen

if auswahl==1:
    addieren(a,b)   
    c=addieren(c) < -----------------
    print(c)
Nun möchte ich das "Funktions c" ind das "Haupt c" schreiben. Das geht scheinbar aber nicht, weil das Funktions c halt nicht verfügbar ist.


Deshlab muss ich mir behelfen, dass ich es so aufrufe:

Code: Alles auswählen

if auswahl==1:
    c=addieren(a,b) 
    print(c)
Ich muss also das Haupt c so deklarieren, dass ich der Funktion a und b übergebe und den Rückgabewert direkt dort hineinschreibe.
Ich muss also beides gleichzeitg machen.
Statt erst die Funktion aufzurufen und dann den Rückgabewert in eine Variable zuschreiben

Code: Alles auswählen

if auswahl==1:
    addieren(a,b) 
    c=addieren(c)
    print(c)
muss ich das in einem Rutsch machen.

Code: Alles auswählen

if auswahl==1:
    c=addieren(a,b) 
    print(c)
So langsam wird es mir beim Ausformulieren gerade klar.
Vielen Dank an euch!!!!!!!!!

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:47
von rogerb
Wie gesagt:

Wenn hier

Code: Alles auswählen

if auswahl==1:
    addieren(a,b) 
    c=addieren(c)
    print(c)
die Zeile

Code: Alles auswählen

c = addieren(c)
abgearbeitet wird, schaut Python zuerst auf den rechten Teil des Gleichheitszeichens:

Code: Alles auswählen

... = addieren(c)
Da "c" bis dahin noch nicht im Haupt definiert wurde, kann Python nichts damit anfangen.

Das ist kein Behelf, sondern die richtige und einzige Vorgehensweise:

Code: Alles auswählen

if auswahl==1:
    c=addieren(a,b) 
    print(c)

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 14:59
von Patsche
rogerb hat geschrieben: Sonntag 24. Oktober 2021, 14:47 Da "c" bis dahin noch nicht im Haupt definiert wurde, kann Python nichts damit anfangen.

Code: Alles auswählen

if auswahl==1:
    addieren(a,b) 
    c=addieren(c) <-------------
    print(c)
Ich bin davon ausgegangen, dass das c, wenn es innerhalb des Funktionsausdrucks geschrieben wird, das Funktions c gemeint ist.
Ist aber eben nicht so.
Das Problem ist eben, dass die Funktion nicht wirklcih das Funktions c zurückgibt, sondern "nur" den Wert, der in diesem Funktions c steht.
Sehe ich es denn richtig, dass man niemals direkt auf Variablen einer Funktion zurückgreifen kann, sondern nur auf deren Inhalt?

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 15:25
von rogerb
Sehe ich es denn richtig, dass man niemals direkt auf Variablen einer Funktion zurückgreifen kann, sondern nur auf deren Inhalt?
Das ist richtig, der Wert ist innerhalb der Funktion an einen Namen gebunden. Bei der Rückgabe an einen Namen außerhalb der Funktion wird nur der Wert an den neuen Namen außerhalb der Funktion gebunden. Namen wie du es zunächst dachtest, werden nicht übergeben.

Genauso ist es auch beim Aufruf der Funktion.

Code: Alles auswählen

addieren(c)
Hier wird nicht die Variable "c" irgendwie in die Funktion verschoben, sondern der Wert, von "c" wird an den Funktionsparameter welcher in der Funktionsdeklaration an der entsprechenden Stelle steht übergeben.

Code: Alles auswählen

def function(a, b):
    print(a)
    print(b)

c = 1
d = 2

function(c, d)

"""
Ausagbe:
1
2
"""

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 15:26
von pillmuncher
Patsche hat geschrieben: Sonntag 24. Oktober 2021, 14:59 Sehe ich es denn richtig, dass man niemals direkt auf Variablen einer Funktion zurückgreifen kann, sondern nur auf deren Inhalt?
Nein, immer noch falsch. Du kannst von außen auf gar nichts innerhalb einer Funktion zugreigen, aber die Funktion kann Werte entgegennehmen - die Argumente - und einen Wert zurückgeben - den sog. return value. Schau mal:

Code: Alles auswählen

def add(a, b):
    return a + b

c = add(a, b)
Hier gibt es überhaupt kein c innerhalb der Funktion, sondern nur a und b und trotzdem bekommst du einen return value.

Tatsächlich macht add(a, b) genau dasselbe wie a + b. Letzteres ist auch nur ein Funktions-Aufruf, allerdings syntaktisch mittels eines sog. Infix-Operators dargestellt. Infix, weil der Operator "in" der Mitte des Ausdrucks steht, nicht davor, wie bei add(a, b). Du fragst dich ja auch nicht, wie du auf das c - oder welchen Buchstaben auch immer - innerhalb der +-Funktion zugreifen kannst. Und außerdem wäre es ziemlich schlecht, wenn man auf die Interna einer Funktion zugreifen könnte, denn dann müsste man überall den aufrufenden Code anpassen, wenn man an diesen Interna etwas ändert. Stell dir vor, irgendeine Bibliothek würde das machen, die von Millionen Programmierern verwendet wird - dann müssten alle diese Programmierer jedesmal ihren Code anpassen, wenn sich an der Bibliothek etwas ändert. Und das ist eben genau der Witz von Funktionen: dass die Interna dem Aufrufer egal sein können, denn der ist letztlich nur an dem Ergebnis interessiert, nicht daran, wie das Ergebnis zustande kommt. Du willst ja auch nicht den Führerschein jedes mal neu machen, wenn an deinem Auto eine Schraube ausgetauscht wird.

Re: Funktionen und Rückgabewerte

Verfasst: Sonntag 24. Oktober 2021, 17:36
von __blackjack__
@Patsche: Nur so allgemein als Ergänzung: Solche trivialen Funktionen die den Effekt von Operatoren nachbauen brauchst Du nicht selbst schreiben. Die gibt es in der Standardbibliothek im `operator`-Modul schon fertig.

Die ``if``/``elif``-Zweige sehen auch alle irgendwie gleich aus. Die unterscheiden sich ja nur durch die Funktion die verwendet wird um aus `a` und `b` den Wert `c` auszurechnen. Und die Funktion wird anhand von einer Zahl ausgewählt. Wenn man also die Funktionen in einer Liste hätte, könnte man die passende einfach über den Index auswählen.

Code: Alles auswählen

#!/usr/bin/env python3
from operator import (
    add as addieren,
    mul as multiplizieren,
    sub as subtrahieren,
    truediv as dividieren,
)


def main():
    a = int(input("Bitte Zahl 1 eingeben: "))
    b = int(input("Bitte Zahl 2 eingeben: "))

    functions = [addieren, subtrahieren, multiplizieren, dividieren]
    print("Was möchten Sie mit den Zahlen tun?")
    print("    1. addieren")
    print("    2. subtrahieren")
    print("    3. multiplizieren")
    print("    4. dividieren")

    index = int(input("Ihre Antwort: ")) - 1
    print("Ergebnis:", functions[index](a, b))


if __name__ == "__main__":
    main()