Code-Verbesserungen für erstes "Programm"

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
dynamic1312
User
Beiträge: 7
Registriert: Montag 22. Januar 2018, 12:46

Hallo,

ich lerne gerade mit dem Buch "Einstieg in Python" - nach ein paar Kapiteln habe ich jetzt ein erstes "Programm" erstellt, was "funktioniert".
Der Code basiert alleine auf dem Wissen der Kapitel.

Deswegen wollte ich euch fragen, wie man den Code optimieren könnte bzw. wo man ihn, bei komplexen Programmen, verändern müsste. Oder einfach was Ihr anders machen würdet.

Außerdem würde ich gerne wissen, wie ich die Funktion "createlist" optimieren könnte - dort möchte ich eine Liste erstellen lassen, sofern die Nutzereingabe 1 ist. Allerdings führt es zu einem Error, wenn ich die Liste nicht außerhalb der Funktion erstelle, deswegen habe ich jetzt ganz oben liste = [] verwendet. Dass ich liste = [] nochmal innerhalb der Funktion nenne hat das anscheinend überhaupt keine Auswirkung. Woran liegt das?

Außerdem würde mich noch interessieren, wie sehr der Bezug zur Mathematik im Allgemeinen ist, zum Beispiel:
1) Welche Anwendung können Bitoperatoren später haben? Ich habe das Kapitel gelesen, aber den Nutzen dahinter nicht wirklich verstanden...
2) Wozu gibt es die Funktion type() oder den Datentyp "bytes"? Wird es mir später auf die Füße fallen, wenn ich das vernachlässige?
3) Habt ihr generelles Tipps was ich noch beachten sollte?

Code:

Code: Alles auswählen

liste = []

def hinzu():
    eingabe = input("Hinzufügen:")
    liste.append(eingabe)

def abfrage():
    print("Möchten Sie ein weiteres Element hinzufügen (1) oder die Liste anzeigen (2)?")
    auswahl = input()

    if auswahl == "1":
        hinzu()
        while auswahl is "1":
            abfrage()
            hinzu()
    elif auswahl == "2":
        print(liste)
        abfrage()
    else:
        print("Ich konnte Ihre Eingabe nicht verarbeiten. Bitte verwenden Sie nur 1 und 2!")
        abfrage()

def createlist():
    print("Möchten Sie eine Liste erstellen? 1 für Ja / 2 für Nein.")
    auswahl2 = input()

    if auswahl2 == "1":
        liste = []
    elif auswahl2 == "2":
        print("Okay, dann nicht.")
    else:
        print("Ich konnte Ihre Eingabe nicht verarbeiten")
        createlist()

print("Herzlich Willkommen beim ListenCreator 3000 v0.1")

createlist()
hinzu()
abfrage()
Vielen Dank im Voraus und viele Grüße
:)
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@dynamic1312: verwende keine globalen Variablen. Alles was eine Funktion an Variablen braucht, bekommt sie über ihre Argumente, und das Ergebnis wird als Rückgabewert zurückgegeben. Das Problem hast Du in `createlist`, da Du dort eine lokale Variable mit Namen `liste` anlegst, die nichts mit der globalen liste zu tun hat. Rekursion ist kein Ersatz für Schleifen. Statt also `abfrage` immer wieder aufzurufen solltest Du eine Schleife benutzen. In Zeile 14 hast Du dann sogar dann eine Endlos-Schleife, die aber nie durchlaufen wird, weil immer wieder `abfrage` aufgerufen wird. Endlosschleife deshalb, weil `auswahl` innerhalb der Schleife nicht verändert wird und deshalb die Abbruchbedingung nie erfüllt wird.

Zeile 13: `is` ist nur bei Objektidentität sinnvoll, Zahlen und Strings vergleicht man mit ==.
Zeile 25: die 2 bei auswahl2 ist unsinnig. In der Funktion gibt es gar keine zwei Auswahlen, die man unterscheiden könnte. Ansonsten ist es besser, statt Nummern Namen zu wählen, die mehr über die Variable sagen.

Hier mal die Überarbeitungen, weil Code mehr als tausend Worte sagt:

Code: Alles auswählen

def hinzu(liste):
    eingabe = input("Hinzufügen:")
    liste.append(eingabe)

def abfrage():
    while True:
        print("Möchten Sie ein weiteres Element hinzufügen (1) oder die Liste anzeigen (2)?")
        auswahl = input()

        if auswahl == "1":
            hinzu(liste)
        elif auswahl == "2":
            print(liste)
        else:
            print("Ich konnte Ihre Eingabe nicht verarbeiten. Bitte verwenden Sie nur 1 und 2!")

def createlist():
    while True:
        print("Möchten Sie eine Liste erstellen? 1 für Ja / 2 für Nein.")
        auswahl = input()

        if auswahl == "1":
            liste = []
            abfrage(liste)
        elif auswahl == "2":
            print("Okay, dann nicht.")
            break
        else:
            print("Ich konnte Ihre Eingabe nicht verarbeiten")

def main():
    print("Herzlich Willkommen beim ListenCreator 3000 v0.1")
    createlist()

if __name__ == '__main__':
    main()
Wenn Du nicht weißt, für was man Bitoperationen und Bytes braucht, dann brauchst Du sie auch nicht.
dynamic1312
User
Beiträge: 7
Registriert: Montag 22. Januar 2018, 12:46

Wow, danke erstmal für das ausführliche Feedback! :shock:

Sobald ich deinen Code zu 100% verstanden habe, werde ich meinen anpassen. :P

Was mich jetzt noch interessieren würde:

1. Direkt nachdem in deinem Code die Funktionen abfrage() und createlist() definiert werden, kommt immer ein while true. Warum?
2. Mittels main() definierst du die Begrüßung und startest die Abfrage, ob die Liste erstellt werden soll - das leuchtet mir ein. Nur warum hast du in
Zeile 35 if __name__ == '__main__': eingefügt? Also welchem Zweck dient das?
dynamic1312
User
Beiträge: 7
Registriert: Montag 22. Januar 2018, 12:46

Habe gerade versucht deinen Code auszuführen, nach der ersten Eingabe bekomme ich folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Users/p/PycharmProjects/Einstieg in Python/1.1 ListenCreator 3000 v0.2 by Sirius3.py", line 40, in <module>
    main()
  File "C:/Users/p/PycharmProjects/Einstieg in Python/1.1 ListenCreator 3000 v0.2 by Sirius3.py", line 36, in main
    createlist()
  File "C:/Users/p/PycharmProjects/Einstieg in Python/1.1 ListenCreator 3000 v0.2 by Sirius3.py", line 26, in createlist
    abfrage(liste)
TypeError: abfrage() takes 0 positional arguments but 1 was given
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@dynamic1312: Tippfehler, muss natürlich so heißen

Code: Alles auswählen

def abfrage(liste):
    while True:
        ...
Die while-Schleifen habe ich eingefügt, um Deine Rekursionen zu ersetzen. Das if __name__ dient dazu, dass eine Datei sowohl als Modul als auch als ausführbaren Programm benutzt werden kann. Als Modul dürfen nämlich nur Funktionen definiert werden, aber sonst nichts passieren.
dynamic1312
User
Beiträge: 7
Registriert: Montag 22. Januar 2018, 12:46

Jetzt bin ich im Kapitel Wahrheitswerte, sprich bei dem was du mittels while True realisiert hast.

Wenn ich es richtig verstanden habe sind Sequenzen immer wahr, wenn diese nicht leer sind, oder?
Sprich:
x = "Hallo Welt" = wahr
x = " " = falsch

oder

Liste = ["Auto", 3, "Baum"] = wahr
Liste = [] = falsch

Ist das vom Verständnis her korrekt?
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@dynamic1312: Das kann man ganz einfach mit der `bool`-Funktion selbst ausprobieren:

Code: Alles auswählen

In [1]: bool("Hallo Welt")
Out[1]: True

In [2]: bool(" ")
Out[2]: True

In [3]: bool("")
Out[3]: False

In [4]: bool(["Auto", 3, "Baum"])
Out[4]: True

In [5]: bool([])
Out[5]: False
Entweder hast du einen Tippfehler gemacht, oder eins der Beispiele entspricht nicht deinen Erwartungen.

Üblicherweise sollten Listen homogen sein, also nur Daten des gleichen (Duck-)Typs beinhalten.
Antworten