Anfänger braucht Hilfe - Funktionen

Probleme bei der Installation?
Antworten
hottyhotty
User
Beiträge: 6
Registriert: Freitag 17. Juli 2020, 23:38

Hallo alle zusammen,

ich bin Neueinsteiger in Python und somit auch gleichzeitig hier im Forum. Akutell habe ich ein Buch um Python zu erlernen und gehe Schritt für Schritt meine Themen durch. Aktuell bin ich bei dem Thema Funktionen und muss als Übungsaufgabe ein Programm schreiben in der ich eine Liste erstellen soll, von der ich den Nutzernamen und das Passwort von der Liste entnehmen soll. Ihr werdet schnell sehen, dass ich einen Fehler gemacht habe. Allerdings verstehe ich nicht, warum ich das nicht so machen kann wie ich es eigentlich machen würde.

Mein Code:

def Login (name,passw):
Liste = [("Test23","Pass22"),("Username1,"Passwort1]
for successfull in Liste:
if successfull == name and passw:
print("you registratet succesfully!")
else:
print("Error! Please try again later!")

Username = input("please enter your username: ")
Password = input("please enter your password: ")


Login (Username,Password)


-------------------------------------------------------------------------------------------------
Im Buch steht in der Lösung, dass ich bei der If-Abfrage folgendes hätte stattdessen schreiben sollen:
if successfull[0] == name and succsessfull[1]==pass:

Ich weiß, dass ich nicht unbedingt das schreiben brauche was im Buch steht, denn es gibt natürlich auch andere Wege um an die Lösung zu kommen. Deswegen wäre es Klasse, wenn mir jemand von euch sagt, warum ich das nicht schreiben kann.

Bitte behaltet im Hinterkopf, dass ich nicht lange programmiere und deswegen auch nicht all zu viele commands im Kopf habe und auch nichts mit "fortgeschrittenen" Erklärungen anfangen kann.

Achja eins noch. Der Nachteil meines Buches ist für mich, dass ich immer nur eine Übungsaufgabe zu den Themen habe. Gibt es jemanden der für mich noch ein paar Übungen zu dem Thema hier und vielleicht nochmal zu dem Thema Schleifen hätte? - Gerne können die Ü.A per PM an mich geschickt werden.
Ich wäre euch da sehr dankbar.

Gruß
Hotty
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hottyhotty: Das Beispiel das Du zeigst ist syntaktisch falsch, das kann also nicht der Code sein den Du hast laufen lassen, oder Du hättest auch dazu schreiben sollen, dass Du einen `SyntaxError` bekommst und wo dem Compiler auffällt, dass das nicht stimmen kann. Also bei Fehlern am besten immer den kompletten Traceback 1:1 hier ins Forum kopieren.

Bei der Bedingung könntest Du Dir einfach mal die Zwischenergebnisse anschauen und mit dem Vergleichen was Du erwartest und schauen an welcher Stelle das dann von dem was Du erwartest abweicht. Wobei Du hier anscheinend Probleme hast den Ausdruck korrekt in seine Bestandteile zu zerlegen, weil man dafür ``and`` als das ansehen muss was es ist: ein binärer Operator wie ``+`` oder ``*``, der rechts und links jeweils einen Operanden stehen hat und die zu einem Ergebnis auswertet.

Gehen wir also mal davon aus, dass es sich um den ersten Schleifendurchlauf handelt, `successfull` also den Wert ``("Test23","Pass22")`` hat. Desweiteren gehen wir davon aus, dass der Benutzer die richtigen Eingaben getätigt hat, also `name` den Wert "Test23" und `passw` den Wert "Pass22" hat. Du erwartest da anscheinend das der Ausdruck bei dem ``if`` einen ”wahren” Wert ergibt, bekommst den aber nicht. Probieren wir das einfach mal in einer interaktiven Python-Shell aus:

Code: Alles auswählen

In [192]: successfull = ("Test23", "Pass22")                                    

In [193]: name = "Test23"                                                       

In [194]: passw = "Pass22"                                                      

In [195]: successfull == name and passw                                         
Out[195]: False
In dem Ausdruck sind zwei binäre Operatoren (``==`` und ``and``) und man muss schauen in welcher Reihenfolge die ausgeführt werden, also welcher stärker bindet. Ähnlich wie Punkt- vor Strichrechnung gilt, bindet ``and`` stärker als ``==``, also kann man sich das implizit geklammert so vorstellen:

Code: Alles auswählen

In [196]: successfull == (name and passw)                                       
Out[196]: False
Jetzt kann man das Stück für Stück auswerten. Erst das ``and``:

Code: Alles auswählen

In [197]: name and passw                                                        
Out[197]: 'Pass22'
``and`` schaut ob beide Operanden ”wahr” sind. Hier sind beide Operanden Zeichenketten und bei Zeichenketten ist jede nicht-leere Zeichenkette ”wahr”. ``and`` liefert entweder den ersten Operanden wenn der ”unwahr” ist, oder den zweite Operanden. Da der erste Operand ”wahr” ist, wird der zweite als Ergebnis geliefert.

Und mit dem wird jetzt der Vergleich mit dem Tupel gemacht, der offensichtlich `False` als Ergebnis hat, denn ein Tupel ist immer ungleich einer Zeichenkette:

Code: Alles auswählen

In [198]: successfull == "Pass22"                                               
Out[198]: False
Dein Fehler ist also in das ``and`` irgendeine Magie rein zu lesen und das nicht als den einfachen binären Operator zu betrachten das es ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hottyhotty: Weitere Anmerkungen zum Quelltext:

Anmelden ist etwas anderes als registrieren.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Zwischen Funktionsnamen und öffnender Klammer für die Argumente kommt kein Leerzeichen. Dafür erhöhen Leerzeichen nach Kommas die Lesbarkeit.

Namen sollten keine kryptischen Abkürzungen enthalten. Wenn man `password` meint, sollte man nicht nur `passw` schreiben.

`Liste` ist kein guter Name, weil Grunddatentypen in Namen nichts zu suchen haben, und der Name auch so gar nichts darüber aussagt was der Wert dahinter denn eigentlich bedeutet. Aber genau dafür sind Namen da.

`sucessfull` ist als Name auch falsch. Was ist denn bitte ein Tupel das ein ”erfolgreich” darstellt? Die Tupel enthalten Anmeldedaten.

Die Buchlösung mit den Indexzahlen ist nicht schön. Entweder entpackt man die Anmeldedaten in der Schleife um den beiden Bestandteilen einen sinnvollen Namen geben zu können, oder man macht aus den Argumenten ein Tupel das man dann einfach mit dem anderen Tupel vergleichen kann.

Zwischenstand, der aber immer noch einen logischen Fehler enthält, denn die Ausgabe ist immer noch etwas unerwartet:

Code: Alles auswählen

#!/usr/bin/env python3


def login(name, password):
    for expected_credentials in [
        ("Test23", "Pass22"),
        ("Username1", "Passwort1"),
    ]:
        if expected_credentials == (name, password):
            print("You logged in successfully!")
        else:
            print("Error! Please try again later!")


def main():
    username = input("please enter your username: ")
    password = input("please enter your password: ")
    login(username, password)


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@__blackjack__: kleiner Flüchtigkeitsfehler, == bindet stärker als and.

Code: Alles auswählen

(successfull == name) and passw
Da successfull ein Tuple und name in String ist, ist der erste Teil immer False und der zweite wird daher nie ausgewertet.
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ups, stimmt. 😳
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
hottyhotty
User
Beiträge: 6
Registriert: Freitag 17. Juli 2020, 23:38

Danke für alle Antworten von euch. Ich versuche mich beim nächsten Threat zu verbessern. Mein Kopf rattert gerade ein bisschen mit euren Erklärungen, aber ich hoffe das das noch klick macht.
Antworten