Funktion definieren und aufrufen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hallo zusammen!

Bin jetzt auf Python 3.1 umgeschwenkt.

Code: Alles auswählen

def liste():
    zettel = []
    artikel=''
    while artikel!="x":
        artikel=input('Artikel hinzufügen:')
        zettel.append(artikel)
        print(zettel)
    return
Ich definiere eine Funktion liste. Diese Liste soll Artikel enthalten. Die Artikel werden der Liste nach Eingabe hinzugefügt, solange nicht x für Artikel eingegeben wird.
Durch beenden der while Bedingung durch "x" wird natürlich auch das x in die Liste aufgenommen, was nicht im Sinne des Erfinders ist, allerdings fällt mir dazu sonst nichts ein...

Die Funktion muss mittels test() in der Shell aufgerufen werden, was ja so sein sollte. Gibt es hier eine Möglichkeit die Funktion so zu gestalten dass sie direkt startet. Man könnte Sie natürlich direkt im Programmcode aufrufen. Wäre das in Ordnung?

Ist der Programmcode soweit ok, oder bin ich auch hiermit abseits der "Linie"?

LG
BlackJack

@mcdaniels: Die Prüfung muss halt zwischen Eingabe und Aufnahme in die Liste erfolgen und nicht am Schleifenanfang. Hier bietet sich eine Endlosschleife an (``while True:``) und nach der Eingabe die Überprüfung, welche bei einem 'x' die Schleife abbricht (``break``), oder vielleicht auch die Liste zurückgibt, was ja auch die Funktion und damit die Schleife beenden würde.

Das ``return`` am Ende kann man weglassen. An der Stelle endet die Funktion ja sowieso und einen Wert gibst Du ja nicht zurück. Das wäre mit oder ohne explizites ``return`` immer ein implizites `None`.

Der Funktionsname ist nicht so gut gewählt. Funktionsnamen sollten eine Tätigkeit darstellen und beschreiben was die Funktion tut.

Du könntest mit Leerzeichen um Operatoren und Zuweisungen etwas grosszügiger sein.
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hi!
Sieht nun so aus:

Code: Alles auswählen

def add_data():
    container = []
    item = ''
    while True:
        item = input('Artikel hinzufügen:')
        if item == "x":
            break
        elif item == '':
            print('Bitte Wert eingeben!')
        else:
            container.append(item)
            print(container)
Englische Variablennamen scheinen irgendwie kürzer und aussagekräftiger. :)

while True: ist also IMMER eine Endlosschleife? Was wird hier eigentlich auf TRUE geprüft?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

mcdaniels hat geschrieben:while True: ist also IMMER eine Endlosschleife? Was wird hier eigentlich auf TRUE geprüft?
Na True. Es wird immer der Ausdruck ausgewertet der zwischen while und : steht.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das `item = ''` kannst du noch weglassen.
Und sinnvoll waere es auch, wenn man den Container uebergeben koennte und wieder zurueckbekommt, das ganze kann man auch mir einem Defaultargument genauso aufrufbar machen, da ist allerdings eine kleine Schwierigkeit drin, das will ich jetzt aber nicht verderben :)
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Danke für die bisherigen Rückmeldungen!

Hätte da noch 2 Fragen betreffend Funktionsaufruf und Weiterverwendung der Variablen/Listen etc. Die Funktion wird mit add_data() aufgerufen. Die Variablen gelten ja nur innerhalb dieser Funktion.

1. Wie kann ich Variablen aus der Funktion an andrer Stelle im Programm abseits dieser Funktion verwenden?
2. Wenn innerhalb eines Programmes eine Funktion aufgerufen wird, wird dies einfach über Funktionsbezeichnung(...) bewerkstelligt?

Code: Alles auswählen

def add_data():
    container = []
    while True:
        item = input('Artikel hinzufügen:')
        if item == "x":
            break
        elif item == '':
            print('Bitte Wert eingeben!')
        else:
            container.append(item)
            print(container)

add_data()
BlackJack

@mcdaniels: Ad 1) Gar nicht. Du kannst aber Werte zurückgeben und die dann ausserhalb der Funktion weiterverwenden.

Ad 2) Die Frage hast Du in Deinem Quelltext doch schon selbst beantwortet!?
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Ad 2) Ja und nein, denn ich wußte nicht, ob das so - obwohl es funktioniert - auch ok ist :-)
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Müsste insofern nicht eigentlich ein return container entsprechend, die Werte ausgeben:

Code: Alles auswählen

def add_data():
    container = []
    while True:
        item = input('Artikel hinzufügen:')
        if item == "x":
            return container
            break
        elif item == '':
            print('Bitte Wert eingeben!')
        else:
            container.append(item)
            print(container)

add_data()
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

return gibt nur die Daten zurück und beendet die Funktion sofort, darum kannst du das break nach dem return weglassen. Die Ausgabe (print) musst du selber implementieren.

Code: Alles auswählen

return_value = add_data()
print(return_value)
oder direkt:

Code: Alles auswählen

print(add_data())
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hello!
return gibt nur die Daten zurück und beendet die Funktion sofort
Es geht mir darum dass ich die Werte der Liste container = [] ausserhalb der Funktion ans Programm übergeben will, damit ich selbige dann weiterverwenden kann.
BlackJack

@mcdaniels: Die Formulierung ist IMHO ein wenig komisch. Alles zusammen ist "das Programm", die Funktion ist auch Teil vom Programm.

Du kannst mit der Liste die da zurückgegeben wird, machen was Du willst. Ausgeben, an andere Funktionen als Argument übergeben, oder direkt in der Funktion, in der Du die Liste als Rückgabewert erhalten hast, etwas damit tun.
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hm.. Ich steh grade wieder total auf der Leitung :(

Ich definiere ja in meiner Funktion eine Liste, die die Daten enthält, die man eingibt -> container. Das Ganze wird über String x beendet. Nun würde ich gerne auf den Inhalt der Variable container ausserhalb der Funktion zugreifen. Es scheitert hierbei jedoch daran, dass die Liste ausserhalb der Funktion nicht vorhanden ist:

Code: Alles auswählen

def add_data():
    container = []
    item = ''
    while True:
        item = input('Artikel hinzufügen:')
        if item == "x":
            return
        
        elif item == '':
            print('Bitte Wert eingeben!')
        else:
            container.append(item)
            print(container)

return_value = add_data()
print('Die Liste enthält folgende Daten: ')
print(return_value)
Ausgabe:
Artikel hinzufügen:a
['a']
Artikel hinzufügen:b
['a', 'b']
Artikel hinzufügen:x
Die Liste enthält folgende Daten:
None
>>>
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du musst hinter dem return ja auch noch einen Namen oder Tupel von Namen angeben, die Du zurückgeben möchtest. Ansonsten wird eben nur "None" zurückgegeben.

Beispiel:

Code: Alles auswählen

def foo(limit):
    return range(limit)

values = foo()
print values
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Ok, eine schwere Geburt :-)

Code: Alles auswählen

def add_data():
    container = []
    item = ''
    while True:
        item = input('Artikel hinzufügen:')
        if item == "x":
            return container
        
        elif item == '':
            print('Bitte Wert eingeben!')
        else:
            container.append(item)
            
list_data = add_data()
print('Die Liste enthält folgende Daten: ')
print(list_data)
Ich danke euch für eure Geduld, die ich - ohne Frage - sehr strapazieren dürfte...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Naja, in Kapitel 4.6 im Tutorial wird das eigentlich erklärt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

mcdaniels hat geschrieben:Ich danke euch für eure Geduld, die ich - ohne Frage - sehr strapazieren dürfte...
Du suchst aber, im Gegensatz zu manch anderem Fragesteller, immerhin selber sinnvoll nach Lösungen und stellst lesbare Fragen.
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Hey!
@hyperion: Ja, ich weiß...
Ich lese es (mehrmals) danach versuch ich es und hab dann irgendwie so ne Art Blockade. Keine Ahnung warum das so ist. Jedenfalls werde ich in Zukunft verstärkt versuchen, euch mit solchen Dingen nicht zu nerven.

Es stört mich ja selber total, dass ich das nicht selbst schaffe (bislang)

@/me: Thx

LG
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

mcdaniels hat geschrieben:Hey!
@hyperion: Ja, ich weiß...
Ich lese es (mehrmals) danach versuch ich es und hab dann irgendwie so ne Art Blockade. Keine Ahnung warum das so ist. Jedenfalls werde ich in Zukunft verstärkt versuchen, euch mit solchen Dingen nicht zu nerven.
Ach das ist doch nicht so schlimm. Ich wollte es nur erwähnen, damit Du da noch einmal nachliest. Jetzt hast Du ja mal praktisch lange daran geknobelt und ich denke das nochmalige Lesen stärkt das Verständnis dafür. Zudem schult es die Fähigkeit, Dokumentationen zu verstehen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
mcdaniels
User
Beiträge: 168
Registriert: Mittwoch 18. August 2010, 19:53

Ich hab es nicht als Kritik deinerseits verstanden. Ich glaube mich nervt "mein Prozessor" namens Gehrin am meisten. :-)
Antworten